Web programmers should know that they should never ever try to implement cryptography themselves.
In particular, that means that no non-security-expert should be touching any of the cryptographic primitives directly. They shouldn't be thinking at the level of AES, SHA-1, etc. Instead, they should be using high-level functions to encrypt and sign messages, and to "hash" passwords.
Why? Because otherwise, people get misled into thinking that:
- AES-256 is "great encryption", despite the fact that they're using it in ECB mode, or using non-random IV values, etc. (In some modes, non-random but unique IVs is okay. In others, not so much.)
- They can use the same symmetric key for encrypting multiple messages (or worse, store the symmetric key in the code for direct use).
- They might even decide to use a passphrase as the key directly, without using any key derivation functions.
- They can use RSA to encrypt data directly.
- They can simply "salt and MD5" their passwords to keep them safe. (If you think rainbow tables are the weakest link, think again.)
Just to be on the same page, none of the above items are okay. If you don't get that, then you shouldn't be touching crypto with a 10-foot pole! (AES-256 is great encryption, but only if you use it properly. "It's not the size that matters, it's what you do with it." :-))
What kind of high-level functions am I talking about? I personally recommend the use of an OpenPGP (for data at rest) or SSL (for data in motion) library. These protocols rigidly specify the correct use of asymmetric, symmetric, and hash algorithms. For example, with OpenPGP:
- It does not use RSA to encrypt data directly, but instead generates a random session (symmetric) key per message (this is important), and uses RSA to encrypt that session key.
- It uses a key derivation function to transform passphrases into keys. (In OpenPGP parlance, it's called an S2K, but I think "key derivation function" is the more standard term.)
- It handles picking a good mode, so you will never end up using ECB.
- It handles key management for you, so you don't have to make ad-hoc decisions about which keys are trustworthy, etc.
Summary: if you're not a security expert, and you're thinking at the level of AES, or SHA-1, or (heaven forbid) MD5, you're doing it wrong. Use a library written by security experts (like Bouncy Castle), that implement protocols designed by security experts (like OpenPGP for encryption, or bcrypt or scrypt for password hashing), instead of rolling your own.
I'm not a crypto expert by any means, but I know enough not to try to design my own ad-hoc protocols. Just to be clear, this entire post is Cryptography 101 material. So if this post doesn't 100% make sense to you, then you definitely should not get anywhere near cryptography.