Should programmers who build websites/web applications understand cryptography? I have no idea how most crypographic algorithms work, and I really don't understand the differences between md5/des/aes/etc. Have any of you found any need for an in-depth understanding of cryptography?

I haven't needed it, but I wonder if perhaps I'm missing something. I've used salt + md5 hash to encrypt passwords, and I tell webservers to use SSL. Beyond that, I can't say I've used much else, nor can I say with any certainty how secure these methods are. I only use them because other people claim they are safe.

Have you ever found a need to use cryptography in web programming aside from these two simple examples?

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.
If this question can be reworded to fit the rules in the help center, please edit the question.

4

They should know enough to know that they shouldn't do it.
–
SLaksFeb 24 '11 at 15:38

@SLaks: +1 100% agree. I wrote an answer to this thread to expand on why this is.
–
Chris Jester-Young♦Feb 24 '11 at 17:23

7 Answers
7

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.

+1, but using the same symmetric key multiple times is fine. That's what the IV is for (otherwise you wouldn't need it).
–
oripSep 5 '12 at 6:04

1

In addition, Colin Percival of scrypt (and other) fame has a great article called "Cryptographic Right Answers" which lays out the bread-and-butter crypto decisions you need to make. SSL is very problematic (key revocation is very hard to implement). More info here: daemonology.net/blog/…
–
oripSep 5 '12 at 6:07

@orip Agree, though I'd say that using the same key with a different IV is usually more useful for the case where your message is longer than your chosen symmetric cipher's block size, rather than for distinct messages, where you'd have no context for keeping track of IVs used for previous messages. Also, agree with Colin Percival's article.
–
Chris Jester-Young♦Feb 18 '14 at 11:52

You don't need to know anything but the very basics about cryptography (what's a hash, what's a salt, roughly how hard it is to crack this encryption or that and so on), but you have to know a fair bit about security in general.

The main security areas you definitely have to be aware of as a web developer:

SQL injection. This is probably the single most dangerous hole a web developer can punch on a system.

Not understanding anything about what you're doing is very dangerous. Not knowing what the difference between a message digest hash and a cryptographic hash can ruin you. Not knowing how to salt can ruin you.
–
IncognitoFeb 24 '11 at 14:09

@user1525 That's what I meant as the very basics of cryptography. You definitely don't need to know how any of the encryuption algorithms actually work.
–
biziclopFeb 24 '11 at 14:11

I appreciate the response, and I agree about SQL injection and other attacks, but I was really asking about cryptography.
–
davidhaskinsFeb 24 '11 at 15:36

2

@davidhaskins Yeah, I just thought it was worth pointing out, because each level builds on the previous one. Knowing how AES works is worth nothing if you fail to secure your application on a more basic level. In my experience this is a trap many developers fall into (I did it several times), to concentrate on encryption and lose sight of its role in the long chain of security.
–
biziclopFeb 24 '11 at 15:40

Doesn't apply just to Web Programmers though, maybe the question should be re-titled "What should programmers know about security?" as they don't need to know more than the basics about Cryptography (as interesting as it is)

Crypto comes in handy in lots of situations. An example we've used is encrypting a session cookie created and set by a Win/IIS host to be used on a LAMP host.

If you are to implement encryption (as opposed to md5/sha1 hashing), some basic terms are important - such as the difference between symmetric and asymmetric encryption. Along with understanding the difference between the two, you should develop an understanding of what you as the web developer needs to do to properly store and secure decryption keys. For example, if developing an application to be deployed on a host over which you don't have full administrative control, like a shared host, vs. deploying on a server where all admins are known and trusted.

In my opinion, you should know everything about cryptography that someone attacking your code will know. You should understand hashes, salt, the non-randomness of random, the major encryption algorithms (RSA, 3DES, AES, etc), SHA-1/MD-5/et al. You don't have to memorize them, but you should at least know that the effectiveness of a hash algorithm and how to make it stronger. You should know what collisions and false positives are. You shouldn't be able to recite the encryption algorithms, but you should be familiar with their benchmarks, which ones are ideal for which scenarios. You should be able to describe and explain symmetric vs asymmetric encryption and when to use each. You should know what PKI is and how it is used. You should know what a certificate authority is and how it interacts with your servers.

Knowing the ins and outs of everything isn't as important as knowing the background of it. What are the benchmarks of certain things (how fast, how strong, weaknesses, etc).

These recommendations are for senior or architect level information. If you're just a web monkey rowing an oar, you don't need to know any of this. Your architect should know this stuff. If you're in charge of the site, designing it, implementing it, etc... then you should be familiar with all of these concepts and able to converse intelligently about them. You don't have to be able to teach it, just accept and disseminate information about it.

You should use bcrypt (Blowfish) to store passwords rather than MD5; it's a much slower algorithm, which means that it's a lot harder for a hacker to guess and check. Also, bcrypt takes a work factor as a parameter, meaning it can get even slower as newer computers are introduced, so it has future-proofing built-in.

As a pretty general answer to these kind of questions I always think that you should try to have a basic understanding of anything that is remotely related to what you do. Of course you need specific detailed knowledge of what you're actually working on. It's very difficult to predict how a certain area is going to evolve, what is going to be "in fashion" or what you will need in the future, so having a wide area of stuff that you have at least "heard of" will keep many doors open.

As far as my personal experience in web programming I found basic notions of asymetric cryptography and that stuff helpful to understand what is going on under the hood. I could have survived without it but I must say I enjoy cryptography and maths so why not.