-
Website
http://www.matasano.com/log -
Original page
http://www.matasano.com/log/1749/typing-the-letters-a-e-s-into-your-code-youre-doing-it-wrong/ -
Subscribe
All Comments -
Community
-
Top Commenters
-
Press Controls
3 comments · 2 points
-
ChrisMtso
12 comments · 1 points
-
Eric Monti
11 comments · 1 points
-
StatlerAndWaldorf
12 comments · 3 points
-
Dave G.
7 comments · 1 points
-
-
Popular Threads
Also, CodingHorror should get an attribution.
If you are able to manipulate what the system is going to encrypt in a cookie or parameter, *especially* for an SSO function, the problems began far before the letters "A-E-S" were typed.
SSO is Serious Business.
If you can't manipulate fields, you can predict them (known plaintext).
If you don't know them, you can brute-force them (repeatedly send garbage until the right items line up). A system that verifies 4 different byte fields at arbitrary positions in the message will accept a forgery after a maximum of 4 billion attempts (2^32).
In the example code, I am curious why the encryption key is hashed before being used in the block cipher. As the key hashing is clearly optional based on the function call, what are the advantages/disadvantages? (Why is the key not hashed every time?). Thanks.
But, it feels wrong, doesn't it? Your password sitting at the left side of the buffer, a bunch of zeros on the right... Could this be a problem? In some cases, YES.
If you were using AES, you'd be fine. Its key scheduling algorithm is good at handling all manner of keys. But if this was RC4, you just recreated the same problem as WEP.
He's hashing the key because he expects to pass an ASCII string to the function. But if he filled a string with random characters from a secure random number generator, he'd already have a real AES key. There'd be no need to hash it. So I'm going to give him the benefit of the doubt that the reason he has the "don't hash me, bro" flag is that sometimes he overloads the argument with a real key instead of a password.
As you have said, a MAC is The Right Thing To Do, and they've known they need to do it for at least a year =).
Or is it assumed that there's something confidential in the payload?
a) Server A connects to server B itself and says "please accept this random nonce as meaning 'admin', once" (or for some short period of time).
b) Server A signs the message "this is admin, trust me" and gives the message and signature to the user to pass to Server B.
The former requires that A and B communicate via a side channel (perhaps using TLS), the latter requires that they share a secret key.
Yeah I don't think the Louis CK reference is hidden here.
Cooperating apps often can't talk directly to each other or share any state more complicated than a key derivation secret, so you still see perfectly reasonable designs where app state is offloaded to a client. But a lot of the time this stuff can just be HMAC'd.
I wrote this post to respond to Some Web Page Somewhere that had an example of "what can go wrong" when you write encryption code, where "what can go wrong" is using ECB instead of CBC, not "you will do everything that can conceivably be done wrong, wrong", as it should have been. I just needed a realistic setting. So encryption is kind of the point, not SSO.
The author clearly states that a MAC is needed. My question is about the key selected for the MAC. Are there any security issues with using the block cipher key to also compute the MAC? Should a separate key be randomly generated for the MAC? Thanks.
The author states that salting the passphrase would do nothing against a dictionary attack in this case. I am confused as to how salting the passphrase before hashing would not provide some protection against dictionary attack on the key. Is SHA1 so fast that salting your passphrase does not significantly increase the time required for a dictionary attack?
For SSO, you have a lot of cookies, all authenticated with a single secret key. Salting buys you nothing.
Reason 983492734 why you should use a high-level library.
Uh, oh. Looks like Disqus uses some hash to identify guest users and you can even "claim" the profile on their site somehow. I'm going to pretend I didn't see that so I can save myself time I don't have monkeying with it.
CBC mode performs (previous-cyphertext -block XOR plaintext-block) before AES encryption.
That means that previous-cyphertext-block should be the same for all the plaintext-blocks, but that should not happens because you have an IV for XOR'ing first plaintext.
(IV != C1) => AES(IV ^P1) != AES(C1 ^ P2) => C1 != C2
even if P1=P2.
Am i missing something?
DAVE THE LASER UNICORN
And CBC?
MIKE TRACY
If you’re encrypting all A’s, the ciphertext blocks will repeat.
While it's not clear, I think he means if they're NOT using CBC, the ciphertext blocks will repeat.
How about this instead of for loop around SHA ?
http://www.daemonology.net/blog/2009-05-09-scry...
His approach certainly is no worse than iterating SHA and most likely is much better. I hope to review it soon.
No, that is the fucking _retarded_ answer. The real answer is that webserver A sends a token to appserver B, which only accepts tokens from webserver A, encrypted or not, performs the function, and returns data to webserver A, which then presents the data in the view layer back to the user. God, are you fucking kidding me with this?
Usually the token expires within a set amount of time and is meaningless to the client.
How about having a 3rd service that both applications have private access to and that stores all data needed for applications, which is identified by the random long key in the cookie?
But I'm still having trouble with the premise here, so believability suffers a bit. Crypto should be a last resort. Not sharing the information is a much better solution. Why is it necessary to give the client this kind of information in the first place? Maybe the two servers are in different parallel universes, and only the client can pass between them? Otherwise I'd expect the client just to have a cookie that validates that server A is sending him/her/it to server B, which is at best just a random number generated by a sufficiently good PRNG.
Why does an attacker get unlimited tries? That seems like a problem in and of itself. Maybe, through the use of a botnet, they can get "enough" tries, but "unlimited" seems like a stretch. And without a botnet, that shouldn't be an assumption at all.
Also, the cookie contains an encrypted password? Really? I guess it's inevitable once you assume that the two servers aren't talking, but it's a bit obvious. It's like the old guy telling the teenage couple that they're going to get it, then watching a zombie werewolf toaster picking the teenagers out of their teeth a few scenes later. Yeah, we saw that coming.
It's reasonably common to see people implementing their own HMAC as:
HMAC(M, K) = MAC( K | M )
(Where K is a block-sized key).
Is that actually OK?
Assuming by "MAC" you mean "HASH" (e.g., SHA), there is a length extension attack where you can append data and calculate the updated hash once you've seen one hash result. That's the reason HMAC has two layers (hash message w/ key, then hash the hash w/ key).
For %!$&^%$!! sake, even WIKIPEDIA gets this one right:
http://en.wikipedia.org/wiki/HMAC
Seriously, I love the work but please stop creating new work via old mistakes.
(and I certainly wouldn't have ever done it that way myself, mainly because I remember rule #1 - don't do it yourself, call the damn library function you fool. Just something I've seen)
"Wait, you're using crypto? Fool! Generate 128 bits of random data, stuff it in a CGI parameter, then have the second web server make a SOAP call to the first one to validate that the data is valid, fresh, and has only been used once."
I've been coding for a very long time and I didn't understand anything but the math, which was quite clearly presented.
From your article, I learned something about crypto, but more importantly I learned that I have no safe understanding of how to implement crypto whatsoever.
That's a very good thing to know.
You may have saved lives and fortunes with this post.
(Overkill? I don't know, maybe I'm just pumped up on laser unicorns in space)
cookie = ENCRYPT(plaintext + HASH(plaintext))
When the server receives the cookie, it decrypts it, separates the plaintext from the hash, and checks the plaintext against the hash. That would stop attackers from feeding you modified cookies, because the plaintext wouldn't even get parsed if the hash didn't match.
Then I got to thinking that you can assume that the attacker can guess at least some of the plaintext, so I wondered if prepending it all with some randomness to get the started EBC would fix that. Say the blocksize is 16 bytes, so add 16 bytes of randomness to the start of the plaintext:
cookie = ENCRYPT(random_bytes + plaintext + HASH(random_bytes + plaintext))
Would that protect against known plaintext? I don't really know my stuff here, so this could be the ramblings of an idiot, but I'm interested to know what flaws are in here :)
If you want authenticity, use a HMAC or a signature. If you want privacy, use encryption. If you want both, use both. With different keys. Trying to make the encryption step do both is setting yourself up for a failure.
always know were your towel is!
"You could tell how many bytes of the MAC matched by watching how long the function took."
It seems like I have two options:
1. discard invalid data in the minimal amount of time, thereby mitigating potential DOS attacks.
2. discard data in the maximal amount of time, thereby eliminating a "timeable function" attack.
Is there any middle ground here? Because, given the two options, I think I'd go with #1. Seems better to minimize the attack surface to millions of script kiddies at the cost of presenting a (small?) attack surface to hardened pros.
___________________
Smarry
Get 28 movie channals for 3 months free