Hacker News new | past | comments | ask | show | jobs | submit login
Typing the Letters A-E-S Into Your Code (2009) (matasano.com)
168 points by zorked on Jan 9, 2015 | hide | past | favorite | 63 comments

I have a comment more on the presentation than the content. I actually really enjoyed the "script format" type presentation more than I thought I would when I first staerted reading it. Having the article be a conversation between two (and more) people helped to explain various aspects of the topic (just as a conversation would normally digress), without getting "single speaker fatigue" as I often get when listening to a traditional lecture. Instead each character had their own voice and personality. The incidental details also helped me picture the scene as if it really were a movie, and brought the content to life in a way simply reading a standard article description would not.

I think this could also be interesting to see in an actually filmed format, and could be applicable to more topics than just security/cryptography. Maybe instead of "Comedians in Cars Getting Coffee" we could have "Computer Scientists in Cars Getting Coffee".

Right now it seems like most of the video content about this field is in either the single lecturer/presenter format, the interview format, or the unscripted Q&A panel format, but I have not seen many (or even any) multicharacter scripted pieces, as the original article presented. It seems like there is room to innovate in this space. Your "characters" could each have different concerns, and their contribution to the topic discussion would be scripted explain the topic in terms of their "personality" (the performance junky, the "paranoid" security person, etc). I'm just talking off the top of my head here, so I'm sure there are some more interesting ways to run with this concept.

If anyone has actually done something like this, I would appreciate if someone could reply with link or some more information about that project. If not I think it could be a project worth pursuing.

On the flipside, if this content had been presented as a video, I would probably have ignored it. And even if the brand power of @tptacek convinced me to watch it, I'd probably have been annoyed at the jokes rather than enjoying them.

Written text leaves a lot of things to the reader's imagination, and therefore gives the reader a lot more freedom to engage with the content in whatever way he likes, at whatever pace he prefers. Some people love to read plays, but not all of them like to watch movies based on those plays.

Imagining a couple of computer scientists ranting about MACs while flying through space with a laser unicorn is fun. Actually watching a lame animation of two people and a unicorn flying though space might be funny the first time, but it quickly gets tired. Sure, you could pull a Peter Jackson and make that video extremely high-quality, but most people have better things to do than making an epic movie out of every blog post, so most videos will end up mediocre anyway. And then we're just wasting bandwidth.

In some ways, it's a tried and true concept


Also used extensively, and to great effect, in Godel, Escher, Bach.

Most of Gödel, Escher, Bach (If you haven't heard of it, read it, take your time, and don't be put off if you don't get everything on the first (or tenth) read.):

"GEB takes the form of an interweaving of various narratives. The main chapters alternate with dialogues between imaginary characters, usually Achilles and the tortoise, first used by Zeno of Elea and later by Lewis Carroll in "What the Tortoise Said to Achilles". These origins are related in the first two dialogues, and later ones introduce new characters such as the Crab. These narratives frequently dip into self-reference and metafiction."


I enjoyed this format as well – it reminded me of a presentation called Deep C, which teaches through a dialogue between an interviewer and two candidates with different levels of understanding.


>> I have a comment more on the presentation than the content

It's a thing: https://www.google.com/?gws_rd=ssl#q=power+of+storytelling&s...

I think this could also be interesting to see in an actually filmed format, and could be applicable to more topics than just security/cryptography. Maybe instead of "Comedians in Cars Getting Coffee" we could have "Computer Scientists in Cars Getting Coffee".

Oh my gosh, this sounds like so much fun! Someone please make this happen. Bonus points if you manage to work in an old-timey silent film scene, complete with plinky piano and over-dramatic reactions.

The now-infamous conference video of Angular introducing Angular 2.0 uses this to great effect.

Do you happen to have a link to that?

Luckily, in PHP land, I can do it wrong without ever having to type the letters A-E-S anywhere, because the relevant mcrypt constants are named MCRYPT_RIJNDAEL_128, MCRYPT_RIJNDAEL_192, and MCRYPT_RIJNDAEL_256.

Nevermind the fact that only MCRYPT_RIJNDAEL_128 is actually AES, most developers choose MCRYPT_RIJNDAEL_256 and claim they're implementing AES-256.

To wit (trigger warning, encraption and severe arrogance on its developer's behalf follows):




And this is an eCommerce platform.

If anyone is feeling frustrated by the constant "don't roll your own crypto" advice from the experts, it's being said for a damn good reason.

Also, don't use opencart's encryption library.

I'm the one that reported issue #1279. The owner of the project has shown that he has absolutely no interest in addressing (or even politely replying to) security issues in his code so I'd advise anyone to steer clear of opencart.

It is out of question that you can do it wrong without typing A-E-S: Crypto is hard, and you can always fuck up in an infinite amount of ways.

That being said, do you have any reference on MCRYPT_RIJNDAEL_256 being an actual problem? The linked OpenCart issues deal with ECB mode and missing authentication, rather than the block size.

It's not really a problem so much as it's not doing what they think it's doing. 256-bit block-size Rijndael might even be better than 128-bit (AES). I don't know.

I'm flattered by the attention, as always.

Couple quick things:

On our original blog (I have nothing to do with this one; I haven't been at Matasano for several months), this was CSS-formatted to look like an actual script, which I think makes it significantly easier to follow. Dave Wagner copied it to his website, and it's closer to the original:


Second: in case you're impatient (I would be), conceptually, this is what the post is trying to communicate:

* Unauthenticated CBC is surprisingly malleable. There are two attacks in here that I thought were "clever": using totally random CBC block garbling strategically to eat quote characters and synthesize SQL injection (the motivating example for the post, after I pulled this attack off on a real system) and "stuffing" inputs with known plaintext to make rewriting easier.

* CBC padding oracles. I would be interested if anyone knows a source outside of academic literature that walked through this attack published prior to 2009.

It is not about how to implement single sign-on cookies.

The nice thing about posts about cryptographic attacks, as opposed to cryptographic constructions, is that they age pretty well. :)

I found this a bit surreal, because the answer in Flask is roughly:

1. Generate a server signing key using urandom(key_length).encode('base-64') and store it in app.config['SECRET_KEY'] via config.py and appropriate .gitignore, or environment variables, whatever toots your horn.

2. You now have a secure signed session cookie, congratulations. This is a "user session data" cookie, i.e. a simple key-value store in the user's cookies accessed from flask via session['key'], so set session['sid'] to some long random .encode('base-64') key that maps to the user via Redis (or your RDB, if you want to only use that).

3. Use Flask's @app.before_request decorator to determine who owns the session ID and store the appropriate user ID in the Flask.g request context.

4. The @app.route gets the user ID from Flask.g, never the session. Any calls it makes that need to know which user are given the internal ID directly (i.e. the user ID in the users table).

A lot of people don't even go to that extent, you can do more or less the same thing via Flask-Login or Flask-KVsession. If you're using either, I'd recommend reading through the project code on GitHub to see what happens as a result of the context decorators. It's not terribly complicated in either case.

So back to the original problem, if you want both services to be able to verify the signing data, you give them the same app.config['SECRET_KEY'] and have them share data about how session keys map to users.

Or you could use an "I am Joe Johnson" cookie schema and forego session keys, if that's appropriate. If so, just put it in session['username'] and let the session sign it. Ta da, done.

If you have to start thinking about encryption strategies in Flask, beyond "use passlib.hash.bcrypt_sha256 on user passwords," you done fucked up already. It has great tools to keep you from ever having to touch that stuff, so please use them.

The above story should be roughly equivalent for Rails, once you change the names around. Node.js, I'm not sure, but there's probably a library for that by now. Use it.

If you think answering the SSO question is the point of this piece, you haven't read it properly.

Obligatory Doom principle link. http://www.thoughtcrime.org/blog/the-cryptographic-doom-prin...

Encrypt Then Authenticate, dammit!

Or, from the inverse perspective: always authenticate and/or verify the integrity of data before processing it at all, whether that processing be decryption, string manipulation, or otherwise.

Which you can't do if the MAC is within the encrypted message.

Of course. EtM is the only way to go. Just saying it can be applied to other areas, too.

Rule of crypto #1 - never implement your own crypto.

If you want to know what they are talking about, here are two free courses that go over all of that stuff and more. I particularly liked error oracle decryption exercise from coursera crypto class:



The Coursera one is amazing. I've been waiting for the second part for years. It's a twist a minute ("so how can you break X?" "okay yeah there is NO WAY to break this at all, I'm positive" "pretty simply: do Y" "goddamnit").

Is this the course you are looking for? https://www.coursera.org/course/crypto2

Yeah, it's been "starting in three months" for two years.

Someone, somewhere had to implement their own crypto, or there wouldn't be any crypto.

Yes, but they did it wrong. But someone else caught the bug and fixed it. But the fix was wrong, but yet another person caught that bug and fixed it. But their fix was wrong, but it got fixed, but that was wrong... and the next, and the next... Repeat for as long as the library has been in active use and development.

That's the value of using established libraries. It's not necessarily that those library authors are so much smarter than the rest of us (although maybe a few are). It's that they already know a lot of the ways that their code was wrong.

If you write it yourself, who's going to catch your bugs? Then who's going to catch theirs?

This is not specific to crypto code, but crypto code is probably harder than most to get right, and more likely to be used on serious stuff.

"those library authors are so much smarter than the rest of us"

Aside from your point (which is valid itself), it's not even necessarily "smarter". Comparably smart people more specialized at task X are likely to be better at task X.

What says any particular person will write said bugs? We have a word for automatically assuming that any particular individual holds any particular trait of the group of which they are a member without first confirming that person has that trait. It's called prejudice. And yes, you can be prejudiced towards your own in-group.

Good crypto code needs a good understanding of crypto and a good understanding of code. The person who has both is rare. Far too frequently, the situation you've described comes about because the only people writing crypto code are the people who understand crypto.

And I think the admonishment "don't write your own crypto code" is peer-pressuring people who have a good understanding of code from abstaining from gaining a good understanding of crypto.

When it comes to putting bugs in software, I am prejudiced against the human race. :-)

Folks saying "don't write your own crypto" are really talking about production systems that will serve customers, employees, governments, etc. Crypto is not going to be a market differentiator; it just needs to work. So why not stand on the shoulders of many others and use a library that is already well tested and patched up?

But in terms of spending your own time to learn, I doubt many folks would say don't do that. Matasano even provides a bunch of freely available materials to do just that.

Someone had to invent the wheel, too, but that doesn't make it a good idea to design and build your own car.

Elon Musk thought it was a good idea to design and build his own car. Should Albert Parcelle, the creator of the first wheel-hub motor, also have abstained from "reinventing the wheel" in 1890? How about J. Grabowiecki with the Omni Wheel in 1919? How about Bengt Ilon forgoing his Mecanum Wheel in 1973?

See, this is why I hate these sorts of statements. They assume it's impossible to be innovative in well-established fields. Or they assume the person they are saying it to is incapable.

It's a sort of arrogant condescension that I don't think should have any place among polite people

No, he didn't. Elon Musk paid a fortune to get experts to design a car for him. He did the opposite of what this thread is debating.

When people say things like "Don't reinvent the wheel" and "Never implement your own crypto", it's generally understood that they mean "unless you have a really good reason for doing so and the budget and expertise to do it right." We don't actually say those things, because we don't want to turn casual conversations into legal documents; instead we trust in the readers' common sense.

But any time any of these sorts of projects come up, the posts are not "what need are you trying to fulfill?", they're just yelling, "don't reinvent the wheel!" That's what I'm talking about, this culture of "I, having spent 5 minutes skimming your README, know better than you."

you can also take matasano's own practical crypto course http://cryptopals.com. If you're taking a vacation, for example, it can be fun to do some of the exercises, write stuff on a notepad, go back to doing exercises and so forth. highly recommended and lighthearted.

I know the cookie example was just an excuse to talk about cryptography but I found it strange that there was no mention of using a randomly generated session ID and a session store as most web frameworks do.

Plaintext SID? Couldn't you just replay that SID then? Or generate random SIDs and see what sticks?

If your SIDs are large enough, it's no different from generating random encrypted cookies until one works, so not practical at all.

The SSO scenario deals precisely with how to pass authentication between two systems which do not have a shared backend datastore.

Well encrypting the data is not really needed. Singing the data is.

Obligatory link if you really want to write A-E-S into your code: Matasano Crypto Challenge http://cryptopals.com/

The article author was involved there too.

There's a portion that says that using SHA-1 for generating a key is bad. Can anyone explain why ?

Because hash functions are really fast, so using them to derive keys from low-entropy sources is really bad: Someone could just iterate over the low-entropy source and get the SHA-1 of each one in virtually zero time.

Brute force is really fast, and hash functions don't help you make it slower at all.

That link is not wrong, but scrypt is probably significantly better than bcrypt, and PBKDF2 is not terrible, if you don't have a handy bcrypt/scrypt library.

But if I use gpg, the default algorithm is CAST-5, so I'll probably still type AES in my code for --cipher-algo AES256 (or API equivalent) :-P (this is mostly in jest, I know that CAST-5 is usually a reasonable default)

Closing with a Futurama quote. Nicely done.

Portions directly copied from comedian Louis C.K.

No. Really? You don't say!

I don't know why they chose to republish this just now, but if you find the original date, you'll see that the reference was much more obvious when we first published it, many years ago.

(The "portion" he's referring to is the Louis CK coffee shop bit.)

His standup on zero knowledge proofs was my personal favorite.

Especially since the NSA has had atleast "a handful of in-house" attacks on AES since 2012. AES(Rijndael) was given a score 1.11 in the AES competition and to put that in context a score of 1.0 is considered a broken cipher. Blowfish scored over 3.0 and was clearly a much stronger candidate algorithm. http://www.spiegel.de/international/germany/bild-1010361-793...

Blowfish? Really? Do you know what you're talking about?

Serpent is the cipher with the score over 3.0 not Blowfish my mistake. But seriously I would read up instead of trusting the conventional wisdom when it comes to the strongest cipher. http://qr.ae/6wveK

The problem with serpent is that it seems to be hard to find a simple to use implementation for a non specialist, and god knows how much review the few implementations around benefited from.

So Serpent appears to be strongest, just slow? Is time really that big of an issue? I mean, why not spend a few extra seconds encrypting something if it is that much more secure?

If by seconds you mean milliseconds ;)

Oh, you're talking about safety factors? Reducing that to a "score" loses a lost of context.

The benefit of the doubt would say they meant Twofish.

The realist says they do not.

> NSA had had at least "a handful of in-house" attacks on AES

That is not what that link says.

"If You’re Typing the Letters A-E-S Into Your Code You’re Doing It Wrong"

What if I'm signing a comment, "MAESTRO"?

... then I'm still doing it wrong. Got it.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact