The majority of this talk is going to be about how to properly store passwords. Just about anything else is beyond the scope of what I can reasonably cover in a short talk and get all the basics covered.
People normally just think of encryption when they hear cryptography but it’s a little more robust than that. Sometimes when you’re storing a value (like a password) you don’t ever need to know that value yourself, just that the person using your website can give you the same input that they gave you before.
IF, by the end of this talk, you’re still completely uncomfortable with these ideas, please talk to us. You probably shouldn’t be writing systems that require logons, and there may be a way to use Shibboleth instead. The obvious benefit is the confidentiality angle, but there are also several other benefits to using cryptography. By having signed data, you can be sure that it originated from the user you think it did, and that it wasn’t changed in the process. It also prevents an authorized sender from denying that they sent the data.
I’ll be saying this word a lot during this talk so it’s best to get this slide out of the way early. When I talk about an algorithm here I’m just talking about a cryptography method to change your data
Hashing always produces an output of the same length, regardless of the size of the initial string. This is why when a system has a maximum length on a password, it’s a very bad sign that the password is probably being stored in plain text somewhere. Asymmetric cryptography is most commonly used to exchange keys in a trusted manner, then the system uses those keys to implement symmetric cryptography. The most common example of this is using HTTPS (SSL/TLS)
The only theoretically unbreakable algorithm is using what’s known as a one-time pad, where a 100% random key that’s never re-used and is as long or longer than the message is used to encrypt the plaintext. This is extremely difficult to do in practice though, due to problems with getting a truly random key, ensuring it’s never re-used, and safely communicating that key to the message recipient.
No cryptography can ever be considered truly secure, it’s only a matter of time. What used to be considered “unbreakable” can now be broken in seconds thanks to faster computers and more clever techniques. Remember Moore’s law says that computing power will continue to double regularly, so you basically need to figure out how long you want something to be secure for, and let that determine your key length. As an example, 2048-bit keys are currently considered good for ~20 yearsAlso, as far as flaws go, the majority of faults in cryptosystems are not with the algorithm itself. For example, not using existing, tested libraries, keeping plaintext in logs or temp files where it shouldn’t be, or sloppy security elsewhere in the system that leads to the keys being compromised.
A rainbow table is basically a set of character strings and their hash values. Someone or multiple someones will generate a list of, say, any random combination up to 32 characters, and hash it with a hashing algorithm like md5. Then when a malicious user runs across a password hash, they can compare it to this master key of values, and if they have a match, they know what your password is. This is much faster to do than it used to be and much of the work has been done already. The faster the hashing algorithm is to run, the faster rainbow tables can be produced for it.Salting: adding extra characters to your plaintext to strengthen it. Should be per-user, and longer is better. If it takes you .001 seconds to encrypt something and you add a salt that takes the processing time up to .01, that’s not really a big deal for you, but if someone is trying to crack your system, every one of the billions of operations they need now take 10 times as long. You can afford it, they can’t. To reiterate: rainbow tables are only used to crack hashing algorithms, and they are severely hindered by strong salts
Don’t Use MD5. MD5 has been around for years and is easily broken with modern hardware. SHA represents a family of algorithms. SHA-1 is pretty well-known and popular, but you should be using SHA-2 if possible. There’s a competition finishing in 2012 to determine what algorithm will be used for SHA-3. The longer the key length you give for SHA hashing, the longer it takes to break. Consider 512 to be your minimum here. The rest of this list is made of more fully-featured encryption libraries that support multiple algorithms for hashing, symmetric, and asymmetric operations.One big caveat here: the library that the rest of these slides are based upon, mcrypt, is not currently installed on www2. It WILL be available on the new server architecture when that is made live later this year. You can also implement a cryptosystem using these same ideas with other libraries.
Most of the information is on the slide here, but basically this is like a nonce for symmetric cryptography. The important thing here is that you use a new one for each user, and keep it available for when you want to validate the user’s password entry. Many times these are just stored in the same field as the password hash, separated by a known character like a dollar sign
If a malicious user gets access to your system and everything they need to reverse or invalidate your encryption is in one place, their job is much easier. Split your information out. A good way to do that is to keep your key in a file on the file system, separate from your web code and db. Symmetric algorithms are slower to run and therefore much harder to crack, and you don’t need to ever get a user’s password (just reset it)Crypto output is binary, so it won’t always go cleanly into a database. By base64 encoding it you know you can put it into a character field safely. Another option (in MySQL) is to use a varbinary columnUsing only ASCII limits the potential of your ciphertext. The more possible values you have, the stronger the encryption
EBC mode encrypts each block of plain text independently, so it’s faster to crack and easier to manipulate. ECB algoignores the IV. CBC mode mashes each block together with its previous blockSome people advise re-running hashing functions multiple times to add processing time, making them harder to reproduce. However, hashing functions already have a number of repetitions built into them. It doesn’t make them more secure, but it does increase the likelihood of collisions. If you’re smart enough to do better than published, tested algorithms, then you should be giving this talk instead of me. If the user’s input is smaller than the key size for the algorithm you can add extra characters up to the maximum length. Having plaintext shorter than the algo’sblocksize doesn’t allow the algo to use its full potential. The last one is really the most important… everything about your crypto system should be able to be known and it can still be secure, as long as the key is kept secret. You also need to make sure that your key is safe… you need it to decrypt your data. Make sure it’s incorporated into your backup strategy, and those backups are at least as secure as its original location
PHP has better cryptography capabilities than mysql does, so if you have to pick one or the other, use PHP and store the encrypted value rather than relying on mysql to do your encryption for you
Cryptography in PHP
Cryptography in PHP<br />
What is cryptography<br />The practice of studying and hiding information<br />Replacing understandable text (plaintext) with a seemingly random set of characters (ciphertext)<br />Covers encryption (hiding) and decryption (revealing)<br />Modern cryptography involves lots of math & computing power<br />
Why use it<br />Because we say so (obviously)<br />“We” here includes ITSO and several state& federal laws<br />Protects user data, and by extension, you, and KU<br />Data breaches can cause national press, and not the good kind<br />The best way to prevent malicious users from getting something is to not store it<br />Confidentiality, Authentication, Authorization, Integrity, Non-repudiation<br />
Algorithms<br />For this purpose, a method used to apply cryptography to text<br />Several categories<br />Many exist<br />Many have known flaws<br />
Types of algorithms<br />Hashing<br />“Digest” <br />One way (non-reversible)<br />Fast, commonly used to verify expected input<br />Symmetric<br />Slower (but that’s not a bad thing)<br />Can be reversed<br />Requires a key (usually known to both parties)<br />Asymmetric – not covered here. Ex. RSA, PGP<br />Typically used in conjunction w/symmetric<br />
Algorithm life-cycle<br />Proposed<br />Rigorously and thoroughly tested in the open for 3+ years<br />Adopted as a standard<br />Broad user base<br />Flaws discovered<br />Declared “broken” and disregarded (but not by all users)<br />Repeat<br />
“You can’t hide secrets from the future with math”<br />- MC Frontalot<br />
Rainbow Tables<br />Compares hashes to known values<br />Fast to search<br />Fast to generate (now)<br />Fit on thumb drives (very soon)<br />
Encryption options in PHP<br />md5() – NO<br />sha1() – there are better ones out there<br />hash()<br />Specify algorithm and key length, sha512 is pretty good<br />crypt()<br />one-way hashing, multiple algorithms<br />Supports bcrypt as of PHP 5.3<br />mcrypt library<br />OpenSSL library – mostly for asymmetric use<br />
Initialization Vectors<br />Used to add randomization to your cipher<br />“seeds” additional randomness into the algorithm<br />Make a new one for each user<br />Use mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)<br />$size should be determined by the algorithm used.<br />mcrypt_get_iv_size($algorithm, MCRYPT_MODE_CBC)<br />IVs can be kept secret but don’t have to be<br />Safe to store them with the encrypted value<br />Not a salt (salting is just for hashes)<br />
Best practices, pt 1<br />Don’t store everything your crypto system needs in one place<br />Use symmetric, one way algorithms for passwords<br />Base64-encode crypto output before storing<br />Keys should be binary, not ASCII<br />Try SHA256 on your key phrase<br />
Best practices, pt 2<br />Use CBC mode instead of EBC<br />Don’t re-run hashing functions<br />Pad out user’s input to cipher’s block size<br />Make sure the input is distinct from your padding<br />Remember to take the padding off when retrieving<br />KEEP IT [your key] SECRET. KEEP IT SAFE<br />
Resources<br />http://www.ciphersbyritter.com/GLOSSARY.HTM - terms<br />https://github.com/archwisp/MindFrame2/blob/master/Crypto.php - example encrypt/decrypt object<br />http://thinkdiff.net/mysql/encrypt-mysql-data-using-aes-techniques/ - encryption functions in MySQL<br />http://www.zimuel.it/blog/2011/01/strong-cryptography-in-php/<br />