Using Encryption and Authentication Correctly(paragonie.com)
paragonie.com
Using Encryption and Authentication Correctly
https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly?resubmit=true
2 comments
This is good. I'd move the "Cryptographic Doom Principle" earlier in the article. I'd make it clearer that even though "encryption" and "authentication" provide two different "services", you can't have encryption without message authentication. Also: I'd consider developing examples with CTR instead of CBC.
We've implemented your recommendations. Glad to hear you liked our post even without the suggested improvements.
Why would you prefer CTR over CBC (assuming properly authenticated)? The only benefit I could think of is performance.
CTR saves you the trouble of padding your plaintext before encrypting, thus eliminating an entire class of cryptography attacks (i.e. padding oracles). The security margins of CBC and CTR are otherwise similar.
GCM is far more preferred to either CBC or CTR because it's less for the implementer to screw up.
NaCl's ChaCha20-Poly1305 is even better, because it's fast and constant-time.
'cperciva made the CTR+HMAC recommendation here: http://www.daemonology.net/blog/2009-06-11-cryptographic-rig...
Properly authenticated encryption that uses CBC+HMAC-SHA2 with PKCS7 padding is probably okay, but new developments should prefer AEAD modes above all else, and CTR+HMAC-SHA2 if no AEAD modes are available.
(The kind folks in ##crypto on freenode have pointed out to me that CTR also allows random-access decryption, where CBC mode does not. We haven't ever implemented this feature and cannot comment on it.)
GCM is far more preferred to either CBC or CTR because it's less for the implementer to screw up.
NaCl's ChaCha20-Poly1305 is even better, because it's fast and constant-time.
'cperciva made the CTR+HMAC recommendation here: http://www.daemonology.net/blog/2009-06-11-cryptographic-rig...
Properly authenticated encryption that uses CBC+HMAC-SHA2 with PKCS7 padding is probably okay, but new developments should prefer AEAD modes above all else, and CTR+HMAC-SHA2 if no AEAD modes are available.
(The kind folks in ##crypto on freenode have pointed out to me that CTR also allows random-access decryption, where CBC mode does not. We haven't ever implemented this feature and cannot comment on it.)
I feel like "if an AEAD mode isn't available, use CTR with HMAC with the following caveats..." is a bit like saying "if you drive without a seatbelt, make sure to drive extra carefully".
Really, if your car doesn't have seatbelts, find an aftermket kit or buy a new car. Likewise, there are BSD-licensed libraries that provide GCM and ChaCha20-Poly1305. These are your aftermarket seatbelt kits for your deathtrap-car of a crypto library.
That being said....
If I were to drive without a seatbelt... CTS instead of CBC mode prevents padding oracle attacks. If you have a flaw that causes IV reuse, CTS and CBC leak less information than CTR mode.
For those driving without seatbelts... CBC and CTR modes do most definitely allow random-access decryption. Seek to block N and decrypt it, then seek to block N-1, read and XOR with the plaintext from your previous decryption. (It's a bit more complicated for the last two blocks of CTS mode, but only a bit.) CBC and CTS do not, however, allow random-access modification, since a single changed bit will on average flip half of the bits in every following block, to the end of the message.
Really, if your car doesn't have seatbelts, find an aftermket kit or buy a new car. Likewise, there are BSD-licensed libraries that provide GCM and ChaCha20-Poly1305. These are your aftermarket seatbelt kits for your deathtrap-car of a crypto library.
That being said....
If I were to drive without a seatbelt... CTS instead of CBC mode prevents padding oracle attacks. If you have a flaw that causes IV reuse, CTS and CBC leak less information than CTR mode.
For those driving without seatbelts... CBC and CTR modes do most definitely allow random-access decryption. Seek to block N and decrypt it, then seek to block N-1, read and XOR with the plaintext from your previous decryption. (It's a bit more complicated for the last two blocks of CTS mode, but only a bit.) CBC and CTS do not, however, allow random-access modification, since a single changed bit will on average flip half of the bits in every following block, to the end of the message.
> Really, if your car doesn't have seatbelts, find an aftermket kit or buy a new car. Likewise, there are BSD-licensed libraries that provide GCM and ChaCha20-Poly1305. These are your aftermarket seatbelt kits for your deathtrap-car of a crypto library.
On mobile devices, this can mean not being able to leverage significantly optimized vendor-provided crypto libraries.
I'd be interested in benchmarking the difference between a decent BSD-license GCM implementation and our use of AES-CBC+HMAC ETM on iOS hardware.
Is there a particular AES-GCM implementation you'd recommend starting with?
On mobile devices, this can mean not being able to leverage significantly optimized vendor-provided crypto libraries.
I'd be interested in benchmarking the difference between a decent BSD-license GCM implementation and our use of AES-CBC+HMAC ETM on iOS hardware.
Is there a particular AES-GCM implementation you'd recommend starting with?
Be very careful with random-access CTR.
Could you please point to an explanation why random access CTR decryption is dangerous? Or why it's more or less secure than random access CBC decryption?
Or is random access CTR encryption dangerous? I don't see how, unless you reuse the keystream / make it a two-time pad.
Or is random access CTR encryption dangerous? I don't see how, unless you reuse the keystream / make it a two-time pad.
https://www.imperialviolet.org/2014/06/27/streamingencryptio...
Thomas's answer probably has to do with the risks of decrypting a stream and being unable to authenticate it first. (See also: the Cryptographic Doom Principle.)
Thomas's answer probably has to do with the risks of decrypting a stream and being unable to authenticate it first. (See also: the Cryptographic Doom Principle.)
But it is still safe to do random access AES-CTR if you've already checked the MAC. Random access is not a problem, decrypting before authenticating is a problem.
I think that's why the statement was "be careful with" rather than "don't"
Can you elaborate? (Either by direct explanation or by reference to something explaining the hazard there?)
[deleted]
crypto.stackex has an interesting discussion on EtM and MtE: http://crypto.stackexchange.com/questions/202/should-we-mac-... One interesting take away was, Bruce Schneier is of opinion that MtE (Cryptographic Doom acc to Moxie) is more practical than EtM.
Interesting to note that different security protocols on the Internet prefer different schemes:
Interesting to note that different security protocols on the Internet prefer different schemes:
1. SSH does Encrypt and MAC
2. SSL uses MtE
3. IPSec prefers EtM
Also see: Authenticating users over REST http://restcookbook.com/Basics/loggingin/ which glances at the details not covered by the blog post (using nonce to prevent replay attacks, for instance).Bruce Schneier was wrong about MtE. This isn't so much a matter of opinion as it is (a) the currently prevailing theory in academic cryptography, at least when it comes to generic composition, and (b) the clear verdict of the last 10 years of crypto vulnerabilities.
Just writing this to be clear: it's not a debate. Ignore Schneier on this. In his defense: the most notable things he wrote about MtE were written before this was well-understood.
Just writing this to be clear: it's not a debate. Ignore Schneier on this. In his defense: the most notable things he wrote about MtE were written before this was well-understood.
Actually Rogaway's new AEZ proposal for CAESAR has a sort of MtE: http://web.cs.ucdavis.edu/~rogaway/aez/aez.pdf
The "MAC" here is just a block of zeros, and if decryption successfully reveals such a block of zeros, then it's deemed authentic.
This is a pretty specific quality to their construction though, and it doesn't really work elsewhere.
The "MAC" here is just a block of zeros, and if decryption successfully reveals such a block of zeros, then it's deemed authentic.
This is a pretty specific quality to their construction though, and it doesn't really work elsewhere.
Yep. "Generic composition" (taking independently designed MACs and cipher modes and rolling your own AE) is my cop-out in case 'pbsd shows up to correct me.
Generally, though, and without intending snark:
If you're discussing MTE v ETM, and Bruce Schneier comes up, the answer is ETM.
Generally, though, and without intending snark:
If you're discussing MTE v ETM, and Bruce Schneier comes up, the answer is ETM.
Encrypt-Then-MAC just makes sense. If the first thing you do when you receive a blob of encrypted data is check that it's authentic (in constant-time!), the attack surface is greatly reduced.
Token-based authentication was covered, in passing, here:
https://paragonie.com/blog/2015/04/secure-authentication-php...
Our strategy (designed for a "remember me" checkbox) is actually a little more cautious than a simple nonce, in that we actually generate two tokens:
One is a selector (used to retrieve a record from the database, which is an operation that cannot be performed in constant time), while the other is a validator.
We store an SHA256 hash of the validator in the database. When the auto-login is invoked, we pull the hash and destination user ID from the database (based on the selector), the compare
https://paragonie.com/blog/2015/04/secure-authentication-php...
Our strategy (designed for a "remember me" checkbox) is actually a little more cautious than a simple nonce, in that we actually generate two tokens:
One is a selector (used to retrieve a record from the database, which is an operation that cannot be performed in constant time), while the other is a validator.
We store an SHA256 hash of the validator in the database. When the auto-login is invoked, we pull the hash and destination user ID from the database (based on the selector), the compare
if (hash_equals(hash('sha256', $verifier), $storedHash)) {
$_SESSION['userid'] = $storedUserId;
$this->generateAndStorePersistentToken(storedUserId);
}
The blog post details it a bit further.