Tips on encryption for storage at rest (AES, SHA??) - security

I wanted to know what is the best way to encrypt storage at rest. Lets say financial information for 1000 users is on a system. Besides making sure nobody unauthorized gets to how do we encrypt the data that is being used everyday so that if god forbid they get it, it should be impossible for them to decode or read?
I believe AES is a correct measure?? How can i implement AES using PHP for phpmyadmin data?

Neither SHA nor MD5 are encryption algorithms, so forget them for now.
The answer to your question is more organizational then technical. First you need to identify what storage you plan to use for the data. If it is the DBMS, then (a) it can offer certain encryption and authentication mechanisms, and (b) you can store the files of the DB on the encrypted storage.
If you have files (either the data itself or the DB with the data), you can store them on encrypted disk. This can be an encrypted NTFS disk or virtual encrypted disk (the one which resides in a file and is mounted as a virtual disk by software).
If you create backups of the data, then backup tools usually offer encryption mechanisms too.
In all of the above cases used algorithms don't matter too much: modern algorithms, offered by above mentioned mechanisms, are secure enough given that you choose 128-bit or larger key for symmetric encryption and choose long passphrase (more than 22 characters if you only use [A-z0-9] alphabet for 128-bit symmetric encryption).
There exists symmetric encryption and public-key encryption (PKI encryption). PKI lets you encrypt the files using public keys (private key is used for decryption), and one of the benefits is that you can encrypt the data for several different private keys. This means that any of the given set of keys can be used for decryption, and the owner of one key doesn't need another key for decryption. The benefit is that you can assign keys to certain users or roles instead of sharing a single passhprase.
The above is just a small guideline and you need to learn a lot (or better involve a security specialist) before you implement the solution, cause security made wrong is worse then no security at all (cause it gives false sense of protection and this makes people careless).

That depends on your platform; most modern operating systems offer disk encryption options with various degrees of security. Note that SHA and MD5 are hash algorithms and thus unsuitable for encryption.
I'd base my choice of algorithm on the capabilities of the system that is supposed to work with the data. Some CPUs have special instructions for AES processing, which gives a significant speed boost here; also, there are harddisk controllers that include encryption support.
Dedicated hardware has two major advantages: it is significantly faster, and it is more difficult to retrieve the symmetric key as a prelude to stealing the actual disk drives.

Related

What's the best place to hide long lived encryption keys

I am considering encryption options for a new Sybase project. I am thinking that Sybase encryption is the wrong strategy because a) dba's can get in, and b) if and when we migrate to SQL Server or Oracle I don't want to deal with different encryption strategies.
Therefore I'm thinking to encrypt the sensitive data (symmetric encryption) in my Java code before storing it in the DB.
Now, the encrypted fields better not have their encryption key changed, ever, except in a very controlled environment, which for me effectively means never. So it's going to be a permanent password.
The question is, where should I keep this password in a way that it is accessible from the program but not accessible to anyone else. If it's in a properties file, any developer with access to our Git repo could see it.
We could hard code it in the source code, but good lawd, that's a bad practice.
We could generate it in source, like the 10th Fibonacci or 3!+8! that would be hard to locate, but it's still rather exposed.
We could have the sa's maintain it in the environment, but then where do they file it for future reference?
So many poor choices. Are there any good ones?
Simply using some secret code to create the key on the fly is both an insecure method and produces a poor key. The DB keep needs to be a random byte array. Keep in mind that the key needs to be in memory when used which will be most of the time for the DB.
WRT using the DB encryption, examine closely if the algorithm is fully specified and compatibility to another DB. There is also the possibility that the entire DB will need to be run-off and then added to a new DB, in that case using the internal DB encryption will be transparent.
You really need to consider needing to be able to change the encryption key in the future, what will you do if it is ever compromised? There are solutions to this dilemma. There may be a substantial performance penalty performing the encryption outside the DB, there is a substantial setup time for each new encryption operation. Also since not all columns will be encrypted (a good guess) that information is not shared by the DB and the outside encryption code, that coupling is not good for design nor maintenance.
Do not connect the DB server to the Internet, make it separate and connected with a non-networked connection such as direct Ethernet. This also limited the number of admin users of the only system that contains the encryption key.
Another important part of the solution is to restrict admin access to the server. This includes requiring two-factor authentication as well as severely limiting the number of administrators. You need to control the second-factor to physical serial-numbered devices owned by the organization so that they can be positively retrieved on personnel changes and not copied. Personally I favor RSA SecureID (or similar) hardware devices, there is positive control.
Finally in answer to the question, keep the key in a file on the DB server secured as above, that is with no Internet access and restricted admin access.

what is the state of the art algorithm to encrypt credit card data

We have a business requirement to keep credit card data. What is today's (Nov 2013) state of the art algorithm to encrypt credit card data that will be saved on disk?
Additionally, I'd appreciate pointers to Java libraries that implement these algorithms
Note that we are PCI compliant and we already store credit card data. I am doing a review to make sure that our encryption method remains state-of-the-art
I recently just left the credit card industry as a developer to work in security in non PCI compliant field. BCrypt is a great choice. It allows a one way hash as well as a work parameter that forces time per attempt. This allows you to stop brut force attacks.
I would use one of the block ciphers approved by ISO/IEC 18033: AES, Camellia, and SEED.
It's hard to go wrong with AES256.
Just go ahead with AES 256 but make sure you choose right mode. I don't agree with comment "It's hard to go wrong with AES256." Check out - https://pthree.org/2012/02/17/ecb-vs-cbc-encryption/
Needless to say, you need to take care of key management and avoid any issues with IV- a message "hello world" encrypted with a key1+IV1 combination will look exactly the same in ciphertext every time you run your encryption. So make sure you are choosing your IVs randomly from a large entropy pool
From Java implementation perspective, Java has native support for AES encryption. Just make sure if you are using 256 bit encryption, you have the right unlimited strength JCE files - without these JCE files which provide crypto methods, you will be limited to 128 bit encryption.
Checkout this if you don't want to reply upon these JCE files available on server running your application.
As #gauravphoenix points out, it is actually quite easy to go wrong with AES. The AES algorithm itself can only securely encrypt exactly 16 bytes of data if you give it a totally random key. If your problem is anything other than that (and almost everyone's problem is something different than that), you need to add more pieces to it. Specifically you need to choose an appropriate mode, configure that mode correctly, properly generate a key, and protect against modification. AES does none of this for you automatically, and unfortunately, most example code on the internet does it incorrectly.
There are a few libraries that attempt to bundle all of these details for you so that you can just make the silly "please encrypt this data" call that most people would like to make. I maintain one for iOS called RNCryptor. There are a bunch of ports of the format to other languages, including a Java implementation called JNCryptor.
Another good "whole solution" AES implementation is aescrypt, which includes a Java implementation.
Note that the most important technical(*) step of securing the data is not your selection of algorithm or format. It's how you manage the keys. If you store the key on the same disk as the credit card numbers, or hard-code it into your software, then it doesn't really matter how strong your encryption is. The state of the art in key management is called an HSM (Hardware Security Module). Companies like SafeNet make them. They can be rack-mounted, plug-in cards, or even USB dongles. I've worked with the Luna, and was generally pleased with it, but there are several options on the market.
(*) While key management is IMO the most important technical step, it is by far not the most important step in securing credit cards (or anything else). The most important step is having procedures in place that encourage secure design, pre- and post-release security review, and a commitment to remediation of security findings.

Aren't private keys vulnerable in memory?

I'm trying to understand what happens when I use a password-protected private key to generate a message digest.
I read here that password-protected private keys are just encrypted using a password-based symmetric key.
Once I enter the correct password, how is a digest generated without exposing the unprotected private key?
At some point the cryptographic primitives in your code will need to access and use the actual value of the key. There's simply no way around that. In a simple analogy, you cannot compute a + b if you don't know a.
The big question concerning secure software design thus boils down to how long sensitive information will persist in an unprotected state. Any sort of password caching is your enemy here, but even if neither the password nor the decrypted key are explicitly cached, they're still in memory at some point. Freezing a computer with liquid nitrogen can keep the memory content intact for a considerable amount of time, and forcing a swap-to-disk is another problem.
Good cryptographic programs should take care to overwrite the memory content as promptly as feasible and minimize the amount of time that sensitive information is retained in readable form. This requires careful analysis of which information is critical (e.g. the user's password input), and platform-specific knowledge of memory management (e.g. can you request non-pageable memory?).
It all depends on your threat model - which sort of attack do you need to protect against? If a rootkit monitors all your memory, you might be in trouble, though that rootkit would probably just read the user's password entry from the keyboard anyway.
This is a complicated issue, and there's extensive research into secure hardware design. In general, the more access an attacker has to your machine, the more likely it is that she'll be able to read sensitive data. Good design can only strive to minimize the surface of attack.
At some point the key has to be available in memory for use by the crypto algorithm.
There have been interesting attacks to try and grab valuable information from memory. One I read about involved plugging a device into a Firewire controller and using direct memory access to poke around for interesting things.
http://www.hermann-uwe.de/blog/physical-memory-attacks-via-firewire-dma-part-1-overview-and-mitigation
It's entirely possible that either a program with necessary privilege to read the memory location holding the key, or hardware utilizing DMA, can grab a private key from RAM.
Generally yes, once decrypted the key will be stored in system memory as cleartext until the application or operating system marks it's address as re-writable. With PGP Desktop, it's possible to manually clear the cached private key, a nice feature I wish more applications offered.
Yes, it is exposed in RAM, and unless the operating system supports protection of memory against paging, and the application uses that feature, the private key can be paged to disk "in the clear." Development tools and active attacks can look for it in memory.
This is one reason specialized hardware cryptographic modules exist. These perform operations with the private key in their tamper-proof memory space; the application can never access the private key itself, it delegates cryptographic operations to the device.

How to properly do private key management

Has anyone got practical experience or a reference for a scheme that implements a key management scheme that would comply with the PCI DSS security standard?
There are obviously quite a few implementations around given the number of companies compliant with PCI DSS but trying to find details of them is tough. When it gets down to storing private data the discussion normally stops at which encryption algorithm to use. After that there's normally a statement about appropriately storing the private key but no discussion about practical ways to do it or things like periodically changing the key or providing the key to applications etc.
Specificlly I'm interested in thee requirements from sections 3.5 and 3.6 of the PCI DSS standard.
3.5.2 Store cryptographic keys securely in the fewest possible locations and forms.
3.6.a Verify the existence of key-management procedures for keys used for encryption of cardholder data. Note: Numerous industry standards for key management are available from various resources including NIST, which can be found at http://csrc.nist.gov.
3.6.4 Verify that key-management procedures are implemented to require periodic key changes at least annually.
I've had a look at the NIST Cryptographic publications as the PCI DSS requirements document suggests but apart from recent notes of a Cryptographic Key Management Workshop there doesn't appear to be much there in the way of real implementable schemes or standards.
As to what I'm trying to do it's not:
Store passwords + salts as one way hashes for authentication,
Choose a strong symmteric algorithm for data encryption,
Avoid needing to store private data in the first place.
Avoid the need for key management with other mechanisms: physical security, database security, dragons and wizards etc.
All of which are valid concerns but in this case are not the answer. The nuts and bolts of my requirements are in a different SO question .Net Design pattern for storing and retrieving sensitive per user data but it all boils down to key management hence this more refined question.
I'm familiar with the pain you're going through. We struggled to update an old EFT system towards PCI compliance. Key management was certainly (from my software point of view) the most challenging part.
I think I also stumbled into the NIST Recommendations for Key Management that Martin posted, and got incredibly frustrated with the lack of concrete examples.
ANSI X9.17 - Financial Institution Key Management is probably the most relevant to your needs, with PCI-DSS. Good luck reading it though, the document is a massive collection of TLA's which I know I certainly struggled to read. (X9.17 is updated yearly, and latest version is now: NIST SP 800-57 Pt. 1 Rev. 4 )
When frustration turned to desperation I stumbled into The Electronic Money Mill which is a fictional tale, with a good number of relevant technical references. Chapter 17 discusses X9.17 and may help with the understanding.
From all this reference material I designed a key management system that our auditor was pleased with. The design documents are fairly lengthy, but in summary the idea is that you have your Data Encrypying Key protected by a Key Encrypting Key, and the Key Encrypting Key is stored on a physically separate box, itself protected by a Master Key.
My implementation was to have a Key Server application running on a windows box. This application required entry of two separate 'key server master keys' before it could be used. These keys would be known only to the key server administrators. These keys are xor'd together to generate the Master Key, which is stored only in protected memory whilst the application is running. Application can then automatically generate cryptographically strong Key Encrypting Keys, which are stored in encrypted form using the Master Key.
Applications that have a need for encryption will request a Key Encrypting Key from the Key Server. The KEK is used by the application to encrypt/decrypt the Data Encrypting Key, which can be stored securely with the application data.
Good luck. I hope you also find it an interesting challenge!
Have you seen NIST SP 800-57, Recommendation for Key Management?

Security risk when store private data

I have to handle some sensitive data in my application, such as passwords, credit card information, etc.
What are possible security risks I could have and how can I avoid them?
Don't store Credit Card Information (in some jurisdictions, you might be breaking the law by doing so, or at least falling foul of a commercial agreement)
You don't say where your sensitive data is stored, but encypting it is the usual approach. There are two forms symmetric and asymmetric. Symmetric means you use the same key for encrypting and decrypting. Asymmetric consists of a public/private key pair.
Passwords: store only a salted hash (i.e. un-reversible) of your passwords, and compare with a similarly salted hash of an entered password.
Be aware that you really shouldn't store credit card info in any shape or form on a web server.
Bit of info on doing this in a web environment, which is my background:
If a website (or any application) needs to store card info, it should comply with the PCI DSS (Payment Cards Industry Data Security Standard). Amongst other things, it requires that the data be held encrypted on a separate server that isn't publicly accessible (IE: isn't hosting the site) and has a separate firewall between it and the webserver. Penalties for not complying are potentially very large in the event of any fraudulent activity following a security breach, and can include them ceasing working with you - it pretty much reserves the right for the them to chargeback any losses from the fraud to you (from my interpretation as a non legal person)
More on it here: https://www.pcisecuritystandards.org/security_standards/pci_dss.shtml
Obviously, this may be expensive compared to shared hosting, as you immediately need two servers and a load of networking gear. Which is why people don't often do this.
I would be inclined to perform some form of reversible encryption on the information as it's being stored, something like:
$card = myEncryptionFunction($input);
A little more information on the nature of your application wouldn't hurt though.
I'd be using reversible encryption on the database data. Make sure this data doesn't seep into log-files too, log derived information instead. Consider how yoǘ'll handle different environments - normally you want to not use production data in your test environments. So even though you may consider copying production data back to test systems, you should probably generate fake data for the sensitive parts.
It's been already said that you shouldn't store CC especially CVV2 information in your database, avoid where possible.
If you store CC + CVV2 then consider using asymmetric encryption and store your private key in another server. Otherwise an attacker who can access the data 99% can access the key and the whole encryption would be pointless.
Passwords should be stored as one way hashed.
After all these you need to ensure that your application is secure against vulnerabilities such as SQL Injeciton, remote code execution etc.
Don't forget Even when an attacker can't read previous data they can plant a backdoor for the next data.

Resources