DISQUS

Matasano Chargen: Typing The Letters A-E-S Into Your Code? You’re Doing It Wrong!

  • StatlerAndWaldorf · 6 months ago
    I would have opened with some exhibition, Chicago loop, street scenes, something with a falafel vendor. Maybe a slow crane shot, build to a zoom into the coffeshop window. Also I think Dave knows from 0x41414141. He would have spotted it in the capture, and circled it in the projection with his laser unicorn horn.

    Also, CodingHorror should get an attribution.
  • dasil003 · 6 months ago
    Thanks for the new hexword: fa1afe1
  • Kr1s · 6 months ago
    Good one! :)
  • Thomas H. Ptacek · 6 months ago
    I don't think Coding Horror wants the attribution.
  • wrc · 6 months ago
    Adding "AAAAAA...AAAA" to the username the server is putting in your cookie?

    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.
  • Nate · 6 months ago
    Any cryptosystem that is vulnerable to a chosen plaintext attack is insecure.

    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).
  • dnasty · 6 months ago
    Please excuse my ignorance.

    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.
  • Daniel · 6 months ago
    I have the same question. No idea why that helps.
  • Thomas Ptacek · 6 months ago
    You would never use a straight ASCII string as a crypto key. The hash gives you 128 bits of key material to use.
  • Nate · 6 months ago
    Well, the question is valid. You could just zero-pad the password string and use it as a key instead of hashing it. Hashing never adds entropy, merely discards a little and shuffles it around equally.

    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.
  • tqbf · 6 months ago
    wrc: it's true. The attack is harder if you don't control any of the plaintext. Now you have to make guesses about what's in it to carry out the same attack. But remember you can iterate over every bit of the ciphertext, changing bits in the decrypted plaintext, and just see what happens.
  • tqbf · 6 months ago
    dnasty --- you know, when I read that code sample on Some Web Page Somewhere, I wondered the same thing --- why is hashing optional?

    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.
  • wrc · 6 months ago
    Tom, you're thinking that I'm thinking what you're thinking, but I'm just speaking in general about SSO and other authenticators. SERIOUS BUSINESS.

    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 =).
  • Nate · 6 months ago
    A digital signature is better than a MAC because it's not symmetric -- ability to verify the signature does not convey the ability to sign arbitrary messages.
  • Bell · 6 months ago
    Why is any more than a digital signature necessary here? All that's required is that the session data can't be tampered with and that the source of the data is a trusted server. The payload encryption seems to be unnecessary and seems to have distracted from the problem of authenticating the messages contents and origin.

    Or is it assumed that there's something confidential in the payload?
  • Thomas Ptacek · 6 months ago
    It's assumed that a lot of SSO tokens are encrypted and are therefore a good excuse to talk about why generalist programmers shouldn't be directly working with AES.
  • curious · 6 months ago
    Why are you encrypting anything? For SSO server B just needs to know that the username was sent by server A. Nicer ways to do this would be:
    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.
  • tatertom · 6 months ago
    After seeing the opening scene absolutely ripped off from Louis CK, the standup comedian, I didn't bother reading the rest. Suck a bag of d1ck5.
  • tqbf · 6 months ago
    A whole bag of 'em? You're angry, right? That's not like, a greeting? "Suck a bag of dicks to you too, sir! A lovely day for sucking several bags of dicks!"

    Yeah I don't think the Louis CK reference is hidden here.
  • tatertom · 6 months ago
    The bag o dicks was another Louis CK reference. I'm not really angry. Its just sad to see someone use another's material as his/her own without giving credit.
  • tqbf · 6 months ago
    Uh, "suck a bag of dicks to you too", also an LCK reference.
  • tatertom · 6 months ago
    Heh. Didn't hear that one. Author's still a bumnugget.
  • tqbf · 6 months ago
    Thanks!
  • interweb · 6 months ago
    tqbf is the Dane Cook of blogging
  • tqbf · 6 months ago
    You mean Carlos Mencia. You're a gay feesh, man!
  • tqbf · 6 months ago
    curious --- you're right, you don't need to encrypt everything. In fact, encryption is getting you into trouble.

    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.
  • tqbf · 6 months ago
    Whoah I'm doing this whole comment thing wrong, I can reply to comments now? It's been awhile since I've been here. What have you all been up to?
  • dnasty · 6 months ago
    tqbf: Thanks for the response to my original post.

    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.
  • dnasty · 6 months ago
    Sorry for the dumb questions, but I am still trying to get my head around some of these cryptology concepts.

    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?
  • Nate · 6 months ago
    Salting increases variation when you have lots of passwords. This way if the password is the same, the hashed copy is not.

    For SSO, you have a lot of cookies, all authenticated with a single secret key. Salting buys you nothing.
  • Nate · 6 months ago
    If you are using some MAC constructions (CBC-MAC), you are providing a decryption oracle if you use the same key for MAC and encryption.

    Reason 983492734 why you should use a high-level library.
  • Nate · 6 months ago
    I'm Nate Lawson, and I approve the words you put into my mouth. Well, maybe not the words but the concept behind them.
  • tqbf · 6 months ago
    There's a problem with this authentication protocol you've come up that I will leave to the reader, or until I figure out something clever to make you say. :P
  • Jordan · 6 months ago
    Which authentication protocol are you referring to? The one where someone puts "Nate" in the name field and we all assume it's actually Nate Lawson?

    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.
  • StatlerAndWaldorf · 6 months ago
    There's POST-based CSRF too, probably with a perfunctory referrer check. I love how they have a POST value called "MiddlewareCSRFToken" that's null.
  • tqbf · 6 months ago
    So... I was just thinking I could alter the post after Nate signed off on it, but I think you guys are on a much more interesting tangent, and have at it!
  • Nate · 6 months ago
    I'm Nate Lawson, and I disavow any association with any modifications to the post since I read it.
  • nh · 6 months ago
    Why in CBC mode generally repeating plaintext blocks should generate repeating cyphertext blocks?
    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?
  • Nate · 6 months ago
    I assume you mean these lines:
    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.
  • tqbf · 6 months ago
    Yeah, it's definitely not clear that I meant to distinguish ECB here. It confused a couple people who reached out to me.
  • Dan Moniz · 6 months ago
    Yay for Nate's mention of cryptlib!; I always wonder why I don't see more people talking about it/using it. Maybe the less than obvious license terms?
  • Steve Weis · 6 months ago
    The moral of the story is that crypto will only break your heart.
  • Nate · 6 months ago
    But it's a good way to make new friends. :)
  • fred · 6 months ago
    Nice Post.
    How about this instead of for loop around SHA ?
    http://www.daemonology.net/blog/2009-05-09-scry...
  • Nate · 6 months ago
    I like the formalism Colin is applying to computational hardness. In the past, you'd talk about complexity in terms of bits of storage and number of operations (e.g., Uli Maurer's work). I haven't yet had a chance to review the math to see if it holds together, but I like that he's thinking about the next level of detail for that kind of problem.

    His approach certainly is no worse than iterating SHA and most likely is much better. I hope to review it soon.
  • Thom · 6 months ago
    Rfc2898DeriveBytes in .NET implements PBKDF2 which is sufficient for any symmetric primitive's key. Also see the paper on key stretching by Schneier et al. Memory-hard algorithms may be ideal, but I'll wait until scrypt gets some cryptanalysis before using it.
  • tqbf · 6 months ago
    See Nate's response above, with the addenda that this seems like one of the less risky places to innovate in a cryptosystem --- it seems hard to get worse than what the default option already is!
  • Thom · 6 months ago
    You can easily get much worse. See the PHP manual pages for proof.
  • Sure · 6 months ago
    A great example of how narrative stories are inferior at conveying information than straight forward technical documentation.
  • Nate · 6 months ago
    Please provide a link to your narrative story that is more entertaining or your technical documentation that conveys information better.
  • mario · 6 months ago
    What? I can't follow this. I'm going to go try to get laid after I eat some soup.
  • or 1=1; · 6 months ago
    "We’ll see if he comes up with the industry standard answer; the cookie both apps honor to let you in, encrypted so users can’t change their account to someone else’s."

    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?
  • or 1=2; · 6 months ago
    someone doesn't understand the point of SSO.
  • or 1=3; · 6 months ago
    You're confusing client-driven SSO, which is the most ridiculous idea ever created in a stateless environment, with server-driven SSO, which is actually workable and is secure without having to jump through cryptographic hoops.
  • Ian Titts · 6 months ago
    I've implemented quite a few SSO for financial websites and we never use client-driven SSO. It doesn't matter if the apps aren't even owned by the same companies, the first webserver always requests a token from the second webserver and passes this to the client to log into the second webserver.

    Usually the token expires within a set amount of time and is meaningless to the client.
  • StatlerAndWaldorf · 6 months ago
    That sounds like a hoot, let's throw six or so more servers into the mix, just for giggles. I admire your certainty! The last person I met that adamant about something was standing on a milk crate on the quad and telling telling me that Jesus didn't want me to smoke. I punched that fucker in the groin. But you, I like.
  • tqbf · 6 months ago
    You are missing the point. I really could care less how you choose to implement SSO. This isn't an article about SSO.
  • steppres · 6 months ago
    TL;DR
  • m0sh3g · 6 months ago
    Wow that's a lot of smart stuff.

    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?
  • chandler · 6 months ago
    Thanks for the morning laughs.

    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.
  • tqbf · 6 months ago
    I'm sure you're right. But I'm not writing about SSO. I'm writing about web crypto.
  • caf · 6 months ago
    This brings to mind a question I've had for a while.

    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?
  • caf · 6 months ago
    Never mind, once I see it written down, it's actually obvious why it's not.
  • Nate · 6 months ago
    No, go directly to Jail, do not pass Go.

    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.
  • caf · 6 months ago
    Yeah, like I said, once seen it written out in my comment the length extension attack was immediately apparent.

    (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)
  • Nate · 6 months ago
    Now you have a zero-day in any system you've seen that does that.
  • Jeremiah Blatz · 6 months ago
    OMG, so many comments. Probably one of them says this:
    "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."
  • Dan · 6 months ago
    Hey, I'm trying to improve my understanding of security related issues, and I can't tell if you are meaning that the example you gave would be a good, or a bad implementation. I would like it if you could comment on which it is, and why.
  • socrates · 6 months ago
    Thanks for the article.

    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)
  • gbensn · 6 months ago
    I've never had to use encrypted session cookies, but I can see why they could be useful, and I've been thinking about how you could secure them. My first idea was to put a hash in there, such that:

    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 :)
  • caf · 6 months ago
    You can come up with all sorts of interesting ideas, but at the end of the day the problems have been solved already: use the existing primitives.

    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.
  • Seth · 6 months ago
    that was informative and entertaining

    always know were your towel is!
  • Nobody Nohow · 6 months ago
    Regarding this:
    "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 · 5 months ago
    I don't think Coding Horror wants the attribution.

    ___________________
    Smarry
    Get 28 movie channals for 3 months free
  • harhar · 6 months ago
    i request samuel l. jackson for the role of thomas ptacek, sylvester stalone for the role of candidate, clint eastwood for mike tracy, and steven seagal as dave the unicorn