
You are dangerously bad at cryptography - alinajaf
http://happybearsoftware.com/you-are-dangerously-bad-at-cryptography.html
======
megrimlock
His insight that crypto is hard because you don't get feedback when you mess
up is good. It made me wonder what other domains are like that -- domains
where correctness seems within reach, yet there are subtle aspects that are
hard to state. Some that come to mind:

* Concurrency. It's easy to introduce race conditions, livelocks, or deadlocks without even knowing. They are often difficult to observe or reproduce, and it takes a lot of hard-won experience to become sufficiently critical of your own incompetence. On the other hand, the tools are improving here (helgrind, relacy, threadsanitizer).

* Exception-safety. I don't mean in the weak sense of "won't leak resources" but in the stronger sense of leaving the system in a consistent state after an exception. Again, it's difficult to analyze or induce all the different code paths that might occur, and difficult or expensive (depending on your starting point) to roll back your mutations. Again, there are tools that help with this, like STM or cheap persistent data structures (so you can do a bunch of mutation that is only committed atomically at the end).

Are there others? Can the progress in these domains shed light on how to make
crypto safer?

~~~
scythe
The biggest candidate:

* Pure mathematics: Consider e.g. the difficulty in verifying the recent proofs of Fermat's Last Theorem (Wiles-Taylor-Frey theorem?), the Poincaré conjecture (Perelman-Hamilton-Thurston theorem?), and now the ABC conjecture (Mochizuki-Szpiro theorem?): there is essentially _no indication_ of the correctness of a mathematical proof besides simply having a whole lot of smart people look at it and think very hard. This may be of particular interest because pure math has lately experienced a turn towards the use of proof-verifying systems, and so it may be of some interest if one of these can be designed for cryptography.

In particular, consider the following method of verification: a
cryptographically secure function h(M, k), known or at least believed to be
hard, a message M, a secret key k, and a channel C(h) over which data is
transmitted. We wish to prove the following combination of statements: a:
given C and h, a method to obtain the message M also obtains the key k, and b:
given M, C, and h, it is "impossible" to obtain the key k -- i.e. it would
require breaking the hash function; this means that if the cryptography is
broken, so must be the hash function. The latter portion of the proof is
necessary because we must always consider the possibility of a rubber hose or
a stupid user.

EDIT: I should add here that _side channel attacks_ depend on an incorrect
understanding of the content of C. So perhaps we should include c: we send
only what we wish to in C.

In the interest of pedantry, I dreamed up an example "cryptosystem" which
_may_ fit the bill, though I have no honest idea of the difficulty of the h
function [and I know almost nothing about cryptography!]: consider a large
prime number p, the finite field F_p, and its algebraic closure Fbar_p. A
message M is a [presumaly long] polynomial M(x) over Fbar_p, and a key
consists of the pair k = [p, z], where z is some arbitrary element of Fbar_p.
h(M, k) is obtained by expanding (x - z) * M(x) in Fbar_p, and we send over C
the coefficients of the resulting polynomial. Verification is obtained by
computing C(z) in Fbar_p and the message is extracted by polynomial division.
Then (a) rests on the difficulty of factoring a polynomial and (b) rests on
the secrecy of p: so we cannot, for example, simply compute C/M.

Note that Fbar_p is _countable_ , so the whole procedure uses only integer
math.

~~~
anonymouz
If I understood your proposed system correctly, the following seems to be a
deal-breaking weakness: Given a number of polynomials representing encrypted
messages, (x-z) is a common factor of all of them. The GCD of a set of
polynomials can very efficiently be computed. Thus, an attacker observing
different messages encrypted with the same key over time gets a better and
better idea of what the key is (how quickly depends on the messages: two
plaintext messages that happen to give coprime polynomials M_1(x) and M_2(x)
would be enough to get the key).

~~~
scythe
In this case, simply computing the GCD may require "non-obvious" intuition,
since the polynomials do not act over the real numbers, but the algebraic
closure of an _unknown_ finite field. But I wouldn't bet my data on it, at
least, not until I am a lot more confident in my understanding of abstract
algebra.

~~~
anonymouz
Ah yes, I missed that the prime is part of the key.

------
tptacek
Note: we're still running these challenges:

<http://www.matasano.com/articles/crypto-challenges/>

The current standings are:

* level 0 (4362 players),

* level 1 (335 players),

* level 2 (123 players),

* level 3 (40 players),

* level 4 (21 players),

* level 5 (23 players),

* level 6 (32 players)

We're still donating $20 to PIH or Watsi for everyone who finishes all 6 sets.

The top languages finishers are using are (in order) Python, Go, Ruby, C/C++,
C#, Clojure, and Haskell. People are also using Java, PHP, OCaml, Scala,
Racket, Javascript, Common Lisp, Perl, Julia(!), erlang, Rust, Visual Basic,
Groovy, ObjC, F#, Factor, Dart, and Microsoft Excel(!!!).

~~~
dsl
Just curious how far the Excel hacker(s) got... Also, have you made any hires
from the contest yet?

~~~
tptacek
All I'm going to say here is that you would not freaking believe how far the
Excel guy has gotten. No VBA, either; it's pure spreadsheet cells.

Yes, we've hired from the challenges (I don't like thinking of it as a
contest; I think of it more as an _extremely engaging_ blog post).

------
e1ven
So, sure. I'll admit that I'm bad at cryptography. You win!

But the problem is, the world needs more, not less, crypto. We need to
integrate crypto into more places, not run and hide and declare it too hard
every time we come across it.

Is it easy to screw up? Sure. So is manually allocating memory. But we use
higher level languages to help protect us from ourselves.

So too can we use higher-level libraries to help protect us from some mistakes
we can make with crypto.

I'm working on an app which uses crypto heavily- In initial versions, I used
manual RSA keys, but I recognize that no matter how smart I think I am (not
very), it's easy to mess stuff up.

I can screw up the padding, I can screw up the implementation. Other clients
which interop with me can screw up...

So Instead, I've swapped to using GPG keys. Is it perfect? Heck no! But it
reduces the code that _I_ have to get right. It outsources the parts that are
most likely to be screwed up to a place where they're more likely to be
reviewed, more likely to be written by non-fuckups.

There are lots of higher level libs, gpg is just one of them. keyczar, etc are
also ways to solve this problem.

But we shouldn't run in fear everytime someone mentions the word Crypto, just
because we have a chance of messing up.

~~~
betterunix
What we really need is a cryptography language, to do for cryptography what
SQL does for databases. I should be able to say, "Messages have this form, and
they need to be encrypted end-to-end with authentication and without
surreptitious forwarding," and have the right components assembled for me.
Unfortunately, our understanding of cryptography is not well-developed enough
to create such a system, and so we still fumble around and usually produce
systems that are vulnerable (did you remember to have a good source of
entropy? did you make sure your messages are all the same length? does your
system compose well with others?).

~~~
dsl
<http://nacl.cr.yp.to/>

NaCl is well implemented cryptographic functions designed to be easy to use
and fast. As opposed to something like OpenSSL that gives you nine million
options, NaCl just does what is best.

~~~
tptacek
NaCl and Keyczar are both good options. We also tend to recommend that people
simply use PGP for data at rest, and TLS for data in motion. Neither are
perfect, but both are subjected to intense scrutiny by researchers.

~~~
alinajaf
> We also tend to recommend that people simply use PGP for data at rest, and
> TLS for data in motion

When I complain about bad crypto (in API auth in particular) and my clients
really _really_ push for me to give them advice, I repeat this line verbatim.

They hate it because TLS with client-side certs for authentication (where you
become the CA) is unfamiliar and has too many moving parts for them. They go
and develop their hand-rolled API auth, I proceed to shoot holes in it and
come across as a bit of dick (to be fair, I'm not hired as a security
consultant, just a regular developer).

I can normally get a few developers on board, but have yet to convince a
client to use TLS in this way in production.

------
jiggy2011
I would break the levels of crypto knowhow down thusly:

1) End user level: You want to buy things online, you should know to check for
the padlock icon.

2) Deployment level: You run an online shop using an off the shelf eCommerce
system. You should buy an SSL cert and know how to install it on your web
server of choice. You should also know the difference between a public and
private key (and hence why you should never give the private key out) and
roughly what a certificate and digital signature are for.

3) Integration level: You are building a custom application/API which uses
crypto for security/privacy. You should know the difference between
symetric/asymmetric encryption, what things like HMACs are and what the
purpose of a password hash is.

You should know how to choose a good library or ensure that your framework is
integrating a good library. You should also be mindful of which information
you should never leak over cleartext channels and also things like MITM
attacks.

4) Implementation level: You are using existing crypto primatives to develop a
new use for encryption, maybe a crypto currency or a new type of auth protocol
for example.

You should know a lot of deep computer science related to crypto, like the
difference between AES CBC and ECB modes, various issues related to padding,
how to generate secure random numbers and countless other issues. Here be
dragons, you probably need significant peer review before your work is
"production ready".

5) Design level: You are trying to improve an existing crypto algorithm or
develop an entirely new one. Here you are going to need a very deep
understanding of mathematics and cryptography research, probably to PHD level.
So all kinds of stuff about number theory and being able to formally prove
everything.

I would guess that most developers should stay at around level 2 as much as
possible, delving into level 3 only when required and never further.

~~~
bashinator
Funny story - quite a few years back I was a sysadmin for a company that was
compiling their own PHP with a couple of patches. When I asked about it, my
co-worker said it was to suppress some warnings that were spamming the logs
whenever someone created an account.

Yes, those warnings were telling us that we weren't using an initialization
vector (IV, aka a salt) when hashing the passwords. Facepalm. I suppose that
demonstrates the dangers of developers thinking they should be diving into
level 3), and also the benefit of (my) being aware of more of the theory than
we should have been implementing ourselves.

Yes, I filed a bug to start using hashes, re-hash all our users' passwords,
and get rid of the patch. This was also well before those massive GPU cracking
systems, so everything turned out fine.

~~~
jiggy2011
Once you are choosing salts that is almost level 4 knowledge. This is one of
the problems with "raw" PHP development, there's no way to say "this is a
password field, make it secure" only "hash this with algorithm X".

To be fair though , I believe recent releases have addressed this and
frameworks like symphony give you a default user class to inherit from that
does things sensibly. It also sticks a seed for the salt directly in the
config file (where devs will see it) and says "make sure you set this randomly
and keep it secret".

~~~
carbocation
Hmm, unfortunately I think Symfony2 runs passwords through 1 round of SHA1
unless a custom password "encoder" is used [1].

[1] = [http://symfony.com/doc/2.0/book/security.html#encoding-
the-u...](http://symfony.com/doc/2.0/book/security.html#encoding-the-user-s-
password)

~~~
terolacu
Bcrypt and PBKDF2 are not custom, they are part of the framework:

[http://symfony.com/doc/current/reference/configuration/secur...](http://symfony.com/doc/current/reference/configuration/security.html#reference-
security-pbkdf2)

~~~
carbocation
Those were added in Symfony2.2; my last experience was with 2.1. Also, I
understand that neither of those is default; one should be.

------
jarrett
This argument keeps coming up, and while its premises are valid, its
conclusion never sits right with me, namely: "Don't use cryptography." That
advice isn't practical for developers. There are plenty of systems we have to
design where crypto is not optional. Examples:

* Storing passwords. You can't store them in plaintext.

* Signing requests (like in the OP's example). What are the alternatives? You can store some kind of authentication in the cookie, which then gets sent with each request. You can use HTTP auth. But in any scenario, you're definitely using SSL, and you're probably using some other kind of crypto on top of that.

* Encrypting cookies. You should store as little as possible in cookies--ideally just a single identifier. But even so, it's very important to make cookies tamper-resistant. You can't, e.g. just have a plaintext cookie that says "userid=42."

So what does the OP propose we do? If this article were making the usual case
that we shouldn't _implement_ our own crypto algorithms, I'd agree 100%. But
he seems to be taking it a step farther, and saying we shouldn't even _use_
existing crypto libraries, because we'll misuse them. But what are the
alternatives?

~~~
kalleboo
> * Storing passwords. You can't store them in plaintext.

Why not. Just write upfront on the signup form, "we don't hash or protect your
passwords in any way. Do not reuse passwords from other sites. Create a unique
password and retrieve it using a password manager."

Password hashing is a losing battle:

* the users who aren't educated enough to use unique passwords are the same ones who will always use a really weak one anyway, and those will always be crackable

* salting is nearly pointless. the GPU killed the rainbow table, the "bad passwords" keyspace is small enough it's easy enough to recompute, and in most hacks I've seen, the database has been compromised together with the source code so the salt is never really secret.

* the first advice after a hack is still always going to be "change your passwords".

~~~
jarrett
> Just write upfront on the signup form, "we don't hash or protect your
> passwords in any way. Do not reuse passwords from other sites. Create a
> unique password and retrieve it using a password manager."

For one, I'd consider that bad business. If you want to make money, it's not a
good idea to declare to users that your system is insecure.

More importantly, you're now putting all the responsibility on the user. Yes,
it's good for users to think about security. Yes, it's impossible to 100%
guarantee the security of your users' passwords. But disclaiming all
responsibility? We're the ones with more technical knowledge, not our users.
We should bear as much of the burden of security as we can.

> Password hashing is a losing battle

Your argument here seems to boil down to the idea that GPUs are now capable of
cracking any password hashing scheme we have, assuming weak passwords. My
understanding was that this was not the case, but perhaps I'm wrong. As far as
I know, you can set the difficulty factor in Bcrypt high enough that it's
impractical to crack on any commodity hardware. There's also scrypt, which is
supposedly even stronger in this respect, although I don't know if it's been
adequately vetted yet.

------
saosebastiao
I'm bad at crypto. I'm well aware that I'm bad at crypto. In fact, I would
venture to guess that I know next to nothing about it. The problem isn't that
I don't know what I don't know...the problem is that I don't know what (or
whom) I can trust. And that is the bigger problem with crypto.

It would be nice if we had resources that could tell us not only the best
practices, but what their downfalls are and their relative difficulties of
cracking. Some common sense tells me that there is a combination of techniques
that are simple and robust enough that I would have to worry about phishing
before I had to worry about better security. But I don't know what that
combination is, and I don't know if I can trust anybody that tells me.

~~~
epsylon
Try Dan Boneh's crypto course on coursera [1]. It covers quite a lot of
ground, both practical and theoretical, and includes programming exercises
similar to the matasano puzzles. Without a doubt it's one of the best courses
of the dozen MOOCs I've taken. There's also a followup course [2] (I haven't
taken it yet personally, but I believe the currently scheduled run will be the
first).

Interestingly enough, there's also an upcoming security course (with no date
planned yet) which will cover the application programming part of security and
will be co-taught by him. [3]

[1] <https://www.coursera.org/course/crypto> [2]
<https://www.coursera.org/course/crypto2> [3]
<https://www.coursera.org/course/security>

~~~
cryptbe
Glad that you like Dan Boneh's crypto class. I made the programming exercises
:-).

~~~
StavrosK
They were very well done, and I loved the course overall, so congrats. I like
how Dan knows how to preemptively answer every question I had.

------
scg
> Measure the time each request takes to complete. Since string equality takes
> a tiny bit longer to complete when the first char matches, the message that
> takes the longest to return will have the correct first character.

Always wondered if this really works in practice ...

I imagined the time it takes to compare 2 strings should be negligible /
indistinguishable in a full HTTP request over the wire. Among all the other
things happening in the network stack, OS, Rails, HTTP, database access, and
everything else you're doing in your request, a string comparison of a few
dozen characters should be well within the noise range.

I've Googled around and it seems like it really is a viable attack:

<http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf>

> We have shown that, even though the Internet induces significant timing
> jitter, we can reliably distinguish remote timing differences as low as
> 20µs. A LAN environment has lower timing jitter, allowing us to reliably
> distinguish remote timing differences as small as 100ns (possibly even
> smaller). These precise timing differences can be distinguished with only
> hundreds or possibly thousands of measurements.

#mindblown

~~~
tptacek
Roughly a hundred people have implemented a milliseconds-granular timing
attack in our crypto challenges. Our challenge isn't totally realistic (in
reality, you'd be timestamping as close to the wire as possible, and if you
used Python, you'd be using it to postprocess samples you took in C) but I
think if you get through it you'll understand why the attack is viable.

Keep in mind that most target applications will allow you to colocate yourself
for ~$100; you just get your sampling server onto a VM in the same hosting
center.

There _are_ programming environments that don't readily admit to over-the-wire
timing attacks. Nate Lawson did a Black Hat talk about this a few years ago.
It is difficult- bordering- on- implausible to remotely time memcmp. It's hard
to say whether it's going to get harder to carry out this attack as machines
get faster, or easier as attackers discover more filtering techniques and
better ways of pessimizing execution on target machines.

~~~
dbarlett
Even better - with some creative "cloud cartography"[1], you have a 40% chance
of launching a VM on the same physical host as your target.

[1]
[https://www.cs.cornell.edu/courses/cs6460/2011sp/papers/clou...](https://www.cs.cornell.edu/courses/cs6460/2011sp/papers/cloudsec-
ccs09.pdf)

------
schabernakk
When he is saying

>Save yourself the trouble. Don't use cryptography. It is plutonium. There are
millions of ways to mess it up and precious few ways of getting it right.

I am sure he means don't use your own homegrown cryptography solution. Use
something established and well tested. Good advice, probably can't be repeated
enough. I liked the exampled he gives, I didnt know for example that you can
basically extend an MD5ed string and keep the original MD5 value. Then again,
I know that MD5 isn't a secure cryptographic hash function so I wouldn't have
used it from the start. Nice to know why thats the case.

~~~
normalfaults
Is there a repository or central location of the established and well tested
solutions for developers to use? Where does one start?

~~~
Osmium
Some ideas, depending on what you need (I can't say how good these are):

<http://www.keyczar.org>

<http://nacl.cr.yp.to>

<https://github.com/jedisct1/libsodium>

<http://www.gnupg.org>

~~~
normalfaults
Thanks. These are straight crypto frameworks which are a good start.

------
jd007
About the timing attack on HMAC that the article mentions. It takes thousands
if not hundreds of thousands of requests to gather the data (and let's assume
you can indeed extract the data out of all the noise cause by network latency
etc...), and any properly designed API should have a throttle measure built in
to prevent brute force attacks like this.

A good, secure API is protected by a variety of measures, not just through the
request authentication component. Of course you should still make your auth as
secure as possible.

~~~
teeja
"a throttle measure built in"

It's my understanding that bittorrent sync uses the latency of the network for
such a throttle. Wild hair: a cyclotron-style router roundabout could hold
millions of packets "in suspension" for n seconds.

------
moakakala
> This means that as long as you have one example of a signed message, you can
> forge signatures for that message plus any arbitrary request parameters you
> like and they will authenticate under the above described scheme.

If all requests are made over HTTPS, how could a third party intercept a
signed message? How is this any greater of a risk than a third party
intercepting user login information? (This is a serious question; I'm not
being flippant or saying 'gotcha')

~~~
jd007
If you do not manage SSL certificate properly (trust only your server's
certificate), a MITM attack can break the system easily. Otherwise I don't
think you can intercept the signed message if everything is over TLS.

~~~
_phred
Right. If the attack vector is "break SSL" I'm going to try some other attacks
first. There's an underlying assumption in the question: my app (and
everything else hosted on the box) is safe from XSS, CSRF, injections, and
other information leakages. Is it really? How do I know for sure?

And who's to say that your forum server (for example) is just as secure? That
could be a foothold into your environment too. And let's not forget social
manipulation of your staff and users. Maybe I'll just steal the machine in
question, or your laptop.

After I try all those avenues, I'm either finding another target or ramping up
for a protracted attack on your SSL connections.

If your site attracts this dedicated of an attack, you'd better get that high
paid security consultant. ;)

~~~
dlitz
The problem with these attacks on SSL is that they're not protracted; They're
trivial. Python's httplib doesn't check SSL certificates _at all_ by default,
for example, so you just hijack the TCP connection, negotiate SSL, and then
you're done.

With libcurl, I think you have to set CURLOPT_SSL_VERIFYHOST to 2. If you set
it to TRUE (i.e. 1), it skips part of the certificate check, rendering the
whole thing trivially insecure.

Most (all?) crypto libraries have terrible APIs, or have APIs that are far too
low-level to be safely used by most developers. SSL shouldn't be the easiest
thing to attack, but in the current state of affairs, it often is.

------
davidw
Saying stuff is hard is easy, and as far as I can tell, very correct about
cryptography.

More useful would be actual suggestions to enable average developers to do
more things with some degree of confidence. In other words, libraries, recipes
and other documentation, and so on.

"Hire an expensive security guy" is probably not a feasible solution for many
small startups, nor very scalable in any case.

Also, out of curiosity, in his timing attack example, the difference in time
caused by the string being equal seems like it'd get absolutely swallowed up
by the random nature of the universe - do those things actually work in the
real world, on real servers with varying loads and numbers of users and
network traffic?

~~~
alinajaf
Hi, author here. I would have liked to have made useful suggestions, but
having made so many errors with cryptography in the past, I don't really feel
qualified to do so.

I do however recommend getting in touch with tptacek and co and doing the
crypto challenges. I mentioned this at the bottom of the post.

Edit: re: timing attacks, it helps if you're in the same data centre. I've
never personally implemented a timing attack, so I'm hesitant to make any
assertions further than that either way.

~~~
bazzargh
btw: isn't the scheme you posted vulnerable to replay attacks too? Much easier
than the timing attack.

edited to add: don't mean this as a nitpick. I've seen that very mistake made
by two S&P 500 companies that had 'homebrew' SSO we had to integrate with.

~~~
alinajaf
> btw: isn't the scheme you posted vulnerable to replay attacks too? Much
> easier than the timing attack.

Yep, probably. In fact now that I look at it definitely, I should have gone
with that instead!

I forget who said this but basically any feature that exists in TLS that
doesn't exist in your hand-rolled authentication scheme is a vulnerability.

~~~
mcintyre1994
Does peer review count as a feature?

------
tveita
Unless I'm missing something, the example code will just calculate the
checksum of "key:value&key:value&key:value", so actually anything with the
same number of parameters will pass.

Assuming "key:value" is supposed to read "#{key}:#{value}", this may be
vulnerable to a delimiter attack -- you couldn't tell the difference between
{foo: 'bar', bar: 'baz'} and {foo: 'bar&bar:baz'}.

~~~
alinajaf
You are of course correct. Thanks! Will fix and rollout once traffic from
HN/reddit dies down.

------
cllns
(Un)conscious (in)competence reminds me of Donald Rumsfeld's trichotomy of
known knowns, known unknowns and unknown unknowns.

(highlighted here: <http://www.youtube.com/watch?v=2Ex8EEv-WPs>)

------
perlgeek
At $work we regularly have trainees who learn just a tiny bit of programming.
We teach them not to touch cryptography if at all possible. And I don't touch
it either.

When we do web development, the admins take care that the application runs
over https, and authentication is handled by some LDAP thingy in the web
server. The only other cryptography we use is ssh, and signing submissions to
the RIPE database with PGP, and stuff transparently done by some database
client libraries.

It seems to be a sweet spot where we're still flexible enough for what we do,
and don't present too much attack surface.

------
almost
I didn't know about Matasano's Crypto challenges. Looks like fun, going to
give it a try!

<http://www.matasano.com/articles/crypto-challenges/>

------
wzdd
I'm just curious: the obvious response to the first problem (message extension
attack) is to include the message length in the message. If this wouldn't
work, could an expert please tell me why?

Edit: To be specific, I was thinking of a Pascal-style length-at-start
arrangement. It's clear that if you put the length at the end you may be
vulnerable to exactly the same attack!

~~~
bazzargh
I'm not an expert, but I can see a problem with schemes along those lines. MD5
(and similar) extension attacks also take advantage of the padding added after
the thing you want to hash; so eg

Secret: secret Message: foo&bar Let's include the length and hash
'secretfoo&bar13'

What you actually hash is 'secretfoo&bar130x80...padding...0x20'. What the
attacker sees as the 'known hash' includes this padding. When you perform an
extension attack, the attack _message_ would look like:
secretfoo&bar130x80...padding...0x02&evil . At this point you're adding on the
length and hashing it, so what you compare with is
'secretfoo&bar130x80...padding...0x02&evil93' ... but the attacker can
precompute _that_ hash just as easily as the one with just 'evil' appended.

You could argue that your hashes would be constructed a bit differently (eg
make messages that appear to have internal padding illegal; still vulnerable,
btw), but the point is - you're still tinkering with the same basic structure,
and are likely to make more mistakes. You're better off switching to HMAC for
this application.

------
JCordeiro
The thing with cryptography is that you have to get it right every time. The
person trying to crack in only has to get it right once.

------
ams6110
I have implemented an MD5-based scheme similar to what was described. At the
time, MD5/hash extension attacks were not as well-known as they are today, at
least I had not heard of them and I read up on MD5 before I designed the
sytem, so another worry is that what is considered secure today might not be
secure tomorrow.

~~~
alinajaf
> another worry is that what is considered secure today might not be secure
> tomorrow

If history is anything to go by then what is secure today will _definitely_ be
insecure tomorrow. No real solution to this AFAIK. If vulnerabilities in the
crypto itself doesn't get you eventually, quantum computing will.

~~~
Dylan16807
Quantum computers can only solve certain types of problems efficiently.
Hashing is not generally in that set.

------
geon
Then there is the question; Is your app likely to ever be attacked at all? By
someone good? With a lot of time?

If not, perhaps hiring a cryptography expert is overkill, and you are better
off just using whatever your framework offers, or integrate some library
yourself. You are not a bank.

~~~
scott_karana
The message extension attack is pretty well known by crackers, which could
leave your webapp open to pre-scripted kit attacks that simply crawl the web.

------
lifeisstillgood
I completely agree with this and have just released a session-cache for python
that completely ignores encryption and just stores uuid in a cookie, and
relies on server side lookups for session work.

~~~
kbaker
Make sure you are using HTTPS exclusively so you aren't vulnerable to
Firesheep-style attacks.

~~~
lifeisstillgood
That's in the docs :-)

Ooops no it's not - kind of assumed it was obvious - thank you for the
reminder :-)

------
idupree
How is the shared secret generated, stored and shared? (There are lots of ways
to do this wrong, and the code and algorithm for that were not even shown.)

------
jimmaswell
For the timing-based one, you I would've made the server wait a small random
amount of time during the process. The xor is more clever, though.

~~~
Filligree
Not the way a naive reading of your post suggests, no.

If you add a random amount of time, the timing attack still works; it averages
out, the same way network jitter does. What you need to do is make every
request take the same amount of time; randomness is not helpful here.

~~~
jimmaswell
I guess I've unintentionally helped prove the article's point, then!

------
andrewcooke
by coincidence, saw this just now
[http://stackoverflow.com/questions/16777091/aes-counter-
mode...](http://stackoverflow.com/questions/16777091/aes-counter-mode-
encryption-library-has-hard-coded-its-initialization-vector)

------
hga
Hmmm, one of the things I've noticed is that if you've studied pre-web
cryptography extensively (as I did, starting even before I started
programming), " _Everything you know is wrong_ ". Or thereabouts.

The HMAC timing attack illustrates this well, "classical" systems as I will
call them, e.g. Enigma and how it was used, are not subject to zillions of
known plaintext attacks (although I've read one bit of known plaintext from an
out of the way base ("I have nothing to report"...) regularly helped the
Enigma decryptors when the key changed).

------
venomsnake
Few thoughts - why MD5 in the example at all? I thought that SHA-2 was the go
to for hash functions nowadays.

And a question on the timing attack - how real it is? Because in the response
time you have a lot of random variables which with the current fast servers
will take more time than the calculation itself.

You receive request - how fast it will go trough the loadbalancer is random,
then you must read the shared secret, then you must log the request somewhere
and the whole hmac calculation is milisecond or less.

~~~
tptacek
SHA2 has the same problems.

~~~
ReidZB
To be more accurate, SHA-224, SHA-512/384, and SHA-512/256 don't suffer from
length extension attacks. The rest of the SHA2 family (256 and 512) do. Of
course, SHA-256 and SHA-512 are more popular than their truncated variants...

------
dakimov
Very good point. I would extend it to security in general.

Security is like medicine: do not try it yourself, unless you are a specialist
or want to end up dead.

Too bad a lot of developers still do not understand this and remain too self-
confident, from what I personally have seen.

