Actually, scratch my earlier - even for whole disk encryption you should be using CTR instead of ECB.
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:
-
Generate a random IV of a length equal to the encryption algorithmâs block size (for 3DES, thatâs 64 bits).
-
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).
-
Initialize the encryptor with the key and the initialization vector.
-
Encrypt your data.
-
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:
-
Pick a reputable cryptographic library, like Bouncy Castle.
-
Pick a high-level abstraction from the library which matches what you want to do (e.g., send a confidential message).
-
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!
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.