
Basic Cryptography Concepts for Developers - paragon_init
https://paragonie.com/blog/2015/08/you-wouldnt-base64-a-password-cryptography-decoded
======
shanemhansen
I once saw a production site that stored the password in plaintext, and then
ran base64(base64()) on the result and sent that in a cookie. It still gives
me nightmares sometimes. That's what I consider to be criminal incompetence.

~~~
haberman
I would love to know why the programmer thought the second base64 would help.

"No one would ever expect the data to be base64-encoded _twice_! Mwa ha!"

~~~
tedunangst
Probably. "Looks like gibberish. Base 64 decode it. Still looks like
gibberish. Must be random bytes." Never mind that random bytes are not likely
to all be ascii letters and numbers.

~~~
startling
Random ascii letters and numbers are just as good as random bytes.

~~~
sarciszewski
Sort of.

There's less entropy per character if you know it will always be alphanumeric
versus a string that of random bytes.

If you take 32 bytes from /dev/urandom and base64 encode it, it has the same
entropy as the original binary string (unless you use it in a way that will
result in it being truncated).

But the total entropy of the two strings is unchanged. One is just longer.

In short: You're correct, but with nuance that bears stating explicitly.

------
elithrar
> "Furthermore, don't confuse password hashing algorithms with simple
> cryptographic hash functions. They're not the same thing:"

"Password hashing algorithms" should probably be replaced with "key derivation
functions" \- which makes it clearer what they are, and makes further reading
(by the reader) into KDFs easier.

~~~
dchest
For Password Hashing Competition ([https://password-
hashing.net/](https://password-hashing.net/)) we tried to come up with a
better term, which describes both password-based KDF and password hashing for
server storage, but couldn't, so it's been decided to keep calling those
things "password hashes".

\- "KDF" says nothing about passwords (e.g. see HKDF) and,

\- "PBKDF" (password-based KDF) says nothing about password verifier, such as
for server storage (e.g. bcrypt doesn't produce a "key"), plus already taken
by specific algorithms,

\- "password hash" sounds good for both key derivation and verifier, but makes
it easy to confuse with normal hashes.

------
jkingsman
Great article for a basic primer, but anyone who is actually developing
cryptography needs to hit a few more books - short articles like this are
great because they make it simple, but that can often lead to the perception
that a dev understands everything they need to, which leads to broken crypto
in production and tears.

~~~
sohkamyung
Reading Ross Anderson's "Security Engineering" is probably a good idea. It
covers security as a system, instead of concentrating just on encryption.

PDF of the first and second editions available at [
[https://www.cl.cam.ac.uk/~rja14/book.html](https://www.cl.cam.ac.uk/~rja14/book.html)
]

~~~
jeff_marshall
Security engineering is a great book. I learned a lot about systems (as
opposed to software) from the first edition. Definitely worth a read for
getting the 'security mindset'. Techniques can be picked up according to the
needs of the job (and should be!)

------
ams6110
I really don't like to see code examples with all the

    
    
      /* Don't ever really do this */
    

comments. Why not show the correct way to do it?

It's not any more clear to see an example of how NOT to do something. And yes,
despite all the comments, someone will copy and paste that into their program,
remove the comments, and then never really properly update the code.

~~~
sarciszewski
Doing things the right way is not very illustrative. This isn't meant to teach
developers how to reinvent NaCl in $langOfChoice, it's meant to instill an
understanding of the vocabulary.

If nothing else, it aims to put to rest stupid phrases like "password
encryption".

If people copy&paste despite all the warnings, they're beyond the help of any
blog post.

EDIT: In the spirit of being more helpful, I've added links to more complete
sample code (on StackOverflow) and made the warnings less obnoxious.

~~~
mckiddy
In that case they should just leave out the examples entirely. If the code
runs, someone in the world WILL copy & paste it into their project and walk
away, no matter if it's marked as insecure or not, which just perpetuates the
problems that the post is trying to deal with.

Also I'm not sure "password hashing" is any more descriptive than "password
encryption."

~~~
sarciszewski
> In that case they should just leave out the examples entirely.

I'll consider it.

> Also I'm not sure "password hashing" is any more descriptive than "password
> encryption."

It absolutely is. Encryption is a two-way transformation of data. It is, by
design, reversible.

Hashing is one-way.

Password hashing is a special case of hashing where you want it to be
computationally expensive (even with special hardware at your disposal) to
attack, but still perform well enough to interact with.

Password encryption implies that a two-way transformation has taken place, and
given the key, you should be able to reverse it. This is _not_ within the
scope of the requirements for secure password storage.

------
nickpsecurity
Funny thing is I did BASE64 a password. Sort of. I used to run strong
passwords + random stuff on paper through SHA-2 with result encoded in BASE64.
Optionally an extra iteration or two for SHA-2. Used BASE64 because it fit the
max number of characters for TrueCrypt passwords: my use case for this method.
Had a tool to make this easier.

Idea was to obfuscate a strong password to make cracking more difficult. Plus,
it was relatively easy to implement on arbitrary computers. These days I just
memorize them or write them on paper.

~~~
paragon_init
If you use bcrypt (which we recommend), you're technically using a variant of
BASE64 too.

The title is a reference to a meme ("You wouldn't download a car!") and also a
reference to some absurdly bad cryptography, e.g.
[http://www.cryptofails.com/post/87697461507/46esab-high-
qual...](http://www.cryptofails.com/post/87697461507/46esab-high-quality-
cryptography-direct-from)

------
anon4327733
I don't quite understand the point concerning executable downloads and
comparing hashes. Yes, comparing a hash found on a file downloaded from
mozilla.com and a hash also on mozilla.com is stupid. However comparing a hash
on mozilla.com and a download/torrent from an untrusted source seems to be
valid and useful. The only attack vector in that case is at mozilla.com and
not the download source.

~~~
sarciszewski
> I don't quite understand the point concerning executable downloads and
> comparing hashes.

Downloading a file from Server A and checking the hash delivered by Server A
is security theater. In this case, only a digital signature (with a pre-
established public key that you already trust) can really stop the server from
being compromised (or malicious).

Downloading a file/torrent from Server B and verifying the hash delivered by
Server A is a different situation entirely, and that boils down to a trust
decision. Do you trust Server A to not be compromised? Do you trust them to
not be malicious or in cahoots with Server B? If not, at the very least it's
probably a larger attack service than the previous scenario. (Trusting the
public key for the digital signature is also a trust decision. Only the
details are different.)

Basically: If you're going to do anything at all, verifying hashes from the
same source is a waste of CPU and human effort.

I hope that helps at all.

~~~
haberman
You made exactly the same point as the post you are replying to, you just used
more words.

~~~
sarciszewski
I wasn't really trying to argue, they said they didn't understand the point.

~~~
meowface
Re-read their post. I think you probably didn't understand _their_ point. :)

~~~
sarciszewski
That's certainly possible. I'm not seeing what I missed. Maybe if I sleep on
it, it will be clearer?

