Why Isn't My Encryption.. Encrypting?

Actually, scratch my earlier - even for whole disk encryption you should be using CTR instead of ECB. :slight_smile:

I don’t think the API’s so great, since it allows you to shoot yourself in the foot so easily. When you first use an API you are completely ignorant, and you want the API designer to have made some good choices for you for default parameters.

The DOCS are rarely much help either, since they fail to provide any judgement about the encryption scheme. Wouldn’t it be good if they said something like if your doing this, then use this encryption, and make sure these options are set, and here’s a real example too. And then have an example with all the right stuff like salting put in and done properly.

Anyway, good post.

am i the only person that thinks using NaCl for the salt is crypto-comedy-gold?

…

uhhh…crypto-comedy-Au?

You might want to take a read over the encryption posts on Good Math-Bad Math as they go over this kind of material: http://scienceblogs.com/goodmath/goodmath/encryption/

NaCL is the new orange imo

this guy knows his chemistry. NaCl. wow.

Ironically, C2H5OH would have been a better salt. Even methane would have salted this better.

So.

MD5 is a bad choice but not for the reasons Darren suggests; the published attacks on MD5 render it unsuitable for message digests and digital signatures, but it’s fine for entropy mixing purposes. The real reason you wouldn’t want to use MD5 is because MD5’s digest length of 128 bits is far short of 3DES’s strongest key size of 168 bits. You’ve dropped about 50 orders of magnitude of cryptographic strength without even realizing it. (Well, not exactly – 3key-3DES has a meet-in-the-middle attack which reduces the work order of a brute force attack to 2^112, but even that is predicated on a high-entropy 168-bit key, which you’ll not get out of MD5.)

You don’t need a salt. A salt is a unique value which is combined with a password before hashing it and storing it for later password authentication. You’re not hashing passwords and then storing them here, so attempting to defeat a rainbow attack doesn’t make sense – it’s not an attack vector for what you’re doing. Adding a salt is cargo culting. Best case scenario, it adds nothing. Worse case scenario, it reduces the strength of the system.

You do need an initialization vector, which is a unique, non-zero parameter used as the first feedback block in block cipher chaining algorithms like CBC and CFB. It doesn’t need to be high-entropy, but it does need to be unique. If you reuse an IV for different plaintexts, an attacker knows that (C1 XOR C2 = P1 XOR P2) and can recover the plaintexts with a small amount of guessing. This is why WEP is no longer considered secure.

Your encryption algorithm should look something like this:

  1. Generate a random IV of a length equal to the encryption algorithm’s block size (for 3DES, that’s 64 bits).

  2. Run the user’s password through a hash algorithm with a digest size equal to or greater than the key size of the encryption algorithm. SHA-256 is a fine choice; just drop the unused bits off the end. Your aim here is simply to diffuse the entropy in the user’s password across the entire key (otherwise big chunks of the key are predictable).

  3. Initialize the encryptor with the key and the initialization vector.

  4. Encrypt your data.

  5. Prepend the initialization vector to the encrypted data.

That said, the only kind of people who should be writing code like that are people who understand why they should be writing code like that. I’m not seeing that here, so a better description of what your algorithm should look like is:

  1. Pick a reputable cryptographic library, like Bouncy Castle.

  2. Pick a high-level abstraction from the library which matches what you want to do (e.g., send a confidential message).

  3. Do what it says.

Seriously. Don’t play with cryptographic primitives in production code.

You guys asking for the API designers to magically make the right choices for you are children. Crypto is complicated. For any given set of defaults, there are simple situations where those defaults are unsatisfactory. If you actually need encryption, take the time to read up on the concepts so that you know what you’re doing - or hire someone who already does.

What really struck me about this post was not the technical bit but the honesty that someone actually admits his mistake (undermining their reputation?). I believe there are maaany other people out there who don’t understand the concepts and do a very bad job at security (as I have to confess myself) - the only reason so little happens is that people don’t know about the many security holes?

Am I missing something? Isn’t it worth noting how you planed on sharing the key?

The irony in this is that someone will inevitably end up here for sample encryption code and blindly copy/paste your flawed code.

i agree with you @jeff when you say the only secret that can’t be compromised is the one you never revealed and also that If it doesn’t have to be sent to the client, then don’t!.
Back in the day when i was freelance, a client called in some friends of mine because he had forgotten the password to the company pop mail account. Do you know what these clever so and sos did? They went and installed packet sniffer on the company network and snatched the password (among many other things) right out of the ether when one of the other company computers tried to pop the company email.
Lesson here, please don’t send sensitive information over the ether. What i usually do here is use a one way hash on the client app that compares this hash with a stored hash of the password in the database. This is the reason the more reputable (and several less reputable) sites instead of sending you your password, simply assign you a new temporary one. Not because they couldn’t be bothered (which could be), but rather because they most often never knew your password to begin with. This makes also the same password reusable(now if only they could register somewhere what algorithms they all use to ease the choice).
The catch here would be what salt to use in order to have the salt unique to each and every password that is hashed. my suggestion would be a certain portion of the users password. where by the fore mentioned portion would be known only to the programmer who implemented the algorithm yet still of little use to him. I welcome better suggestions for a method to choose the salt and a better algorithm.

I have a reasonable grasp of encryption concepts

I am sorry Jeff, but you have just shown that you know bugger all about cryptography! Seriously consider reading some Bruce Schneier books and then re-evaluate all the places you use any form of cryptography.

Bah! I’m rather sure none of those issues would ever happen with on oldskool C/C++ encryption lib.
You MSIL freaks! :wink:

Jeff -

ECB does have it’s uses, especially when errors in transmission are possible. A single bit error will corrupt only the received vector with ECB, but with CBC all following vectors will also be corrupt.

The main problem was best described by Stevie Wonder: when you believe in things you don’t understand…Superstition is the word.

  • Lepto (nambla)

Wow… This is scary…
I think my advice would be: describe the functionality of the system and then hire someone who knows how to implement it properly.
To illustrate the point: your GP doctor does not do heart surgeries. And there is a reason for that…

Boy, what sites do you guys work on?

Honestly, if I just used rot13, that would probably be enough to keep anyone interested in snooping out of most of my sites. All you have to do is make it more of a pain to read than the information is worth.

Heck, with most of my websites, I could even email you the information, and it still wouldn’t be worth your effort to double click on the message to read it.

If I really have to encrypt, I use SSL certificates on my server. Then, the encryption is handled by the webserver, and I don’t have to worry about a programmer making a dumb mistake. Let the professionals handle the problem, and try not to reinvent the wheel.

Their seem to be all kinds of reasons that MD5 is a bad idea. What about gzip? Gzip the data before the crypto and any changes in the input will get spread across the whole message. This might be improved by ordering data in the message to place changing data at the start or end.

Base 64 conversion is not encryption, It is encoding!!
Please correct me if i am wrong.
Its like converting a decimal to hexa…

Please do not use the advice given in the comments here. Most of it is VERY wrong.