Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Current Crypto Best Practices
198 points by msingle on Apr 5, 2017 | past | web | 68 comments
For a run-of-the-mill programmer, where are some places that I can look for crypto best practices? Eg. For storing passwords, Coda Hale's https://codahale.com/how-to-safely-store-a-password/ looks like it is still relevant, but how do I know that? I know that cperciva and tptacek are some go-to people on HN, but where can I point other non-HN readers?

If you come from a computer science/math background, and want an intro to cryptography in general, I can strongly recommend the Coursera course from Stanford University by professor Dan Boneh - https://www.coursera.org/learn/crypto. To really understand the implementations of security libraries and tools, one should be at least familiar with the fundamentals and terminology of crypto. Otherwise you are blindly encrypting things without being aware of whether you are actually securing things.

The course is free and takes 6 weeks long, and is very interesting if you had never dwelled too deep into security or crypto. There's also a new cryptography class that will be available in September of 2017 - https://www.coursera.org/learn/crypto2.

TBH this doesn't really give you anything about best practices though. It's a bunch of base theory without anything about timing analysis, etc. It's nice to know information but I don't think it makes you a better 'secure' programmer.

This was a complaint I heard from several people I work with who took the course.

To my knowledge there has never been a timing attack documented in the wild on a remote server. They are only practical in offline scenarios with host access

Funny you should mention this in a thread about Dan Boneh's crypto class.

David Brumley and Dan Boneh, "Remote Timing Attacks Are Practical." In Proc. USENIX Security Symposium, 2003. https://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf


Timing attacks are usually used to attack weak computing devices such as smartcards. We show that timing attacks apply to general software systems. Specifically, we devise a timing attack against OpenSSL. Our experiments show that we can extract private keys from an OpenSSL-based web server running on a machine in the local network. Our results demonstrate that timing attacks against network servers are practical and therefore all security systems should defend against them.

Depends on what you mean by timing attack.

The only vulnerability of Tor, which heavily depends on cryptography, is timing analysis.

One of the most important lessons of cryptography is that it doesn't exist in a vacuum. Timing between messages and message sizes can be enough to end you.

I guess "timing analysis" means something else, more akin to correlation of meta-data. https://en.wikipedia.org/wiki/Timing_attack is pretty clear, so maybe I was referring to something else than the OP.

I loved the first crypto course.

I have been enrolled in the crypto2 class for several years now. I hope they finally offer the course, but I have low hopes.

any day now :^)

Cryptographic Right Answers is a good place to start


The original from tqbf: https://gist.github.com/tqbf/be58d2d39690c3b366ad

It's definitely completely relevant today. Find out what you want to do and check that list.

A few things I would update:

* password handling -> Scrypt or Argon2

* Client-server application security -> TLS or Noise

* Hashing/HMAC algorithm -> Blake2/prefix-MAC or KangarooTwelve/KMAC

* Fingerprint -> TupleHash

* key derivation -> HKDF or SHAKE or BLAKE2X

And of course for each of these items, if a NaCL/libsodium solution already exist, just use it.

Why would you make those updates? I like Noise more than I like TLS, but if you look at the recommendation where it says "use TLS" and ask yourself "how would I as a Python application programmer actually use Noise", I don't see the applicability.

Similarly: I like Blake2 more than I like SHA-2, but SHA-2 is universally available and strong (in the context of those recommendations, I also didn't want to explain the difference between SHA-2's HMAC and Blake2's keyed hash MAC). And, of course, part of the point of recommending SHA-2 was to recommend against Keccak. :)

I don't think I actually made a key derivation or fingerprint recommendation. I like HKDF!

> "how would I as a Python application programmer actually use Noise", I don't see the applicability.

Depending on who that list is for I could agree with you.

This recommendation comes from the fact that I'm seeing a LOT of companies who want to have their own secure protocol on top of whatever protocol and end up re-inventing the wheel to avoid the bloatness of TLS. Noise is a good advice for these custom made protocols. I wouldn't replace TLS in the advice, but add a note: "if you really do not want TLS, there is Noise, but that's it!

> Similarly: I like Blake2 more than I like SHA-2, but SHA-2 is universally available and strong

Agree, but if we want to move to nicer/stronger algorithms we must start recommending them at some point. I want to see a push for Argon2/Blake2/SHA-3 in general.

> part of the point of recommending SHA-2 was to recommend against Keccak

Ah well, Keccak is so interesting (not only for hashing) that I would be sad if it end up not being used in the next decades to come. If you're feeling this way because of the efficiency: that's why I recommended KangarooTwelve, if you're feeling this way because of the crappy spec: alright you win.

> I don't think I actually made a key derivation or fingerprint recommendation. I like HKDF!

What are you waiting for! :)

There's more recommendations I could make; for instance, I talk about DH here but not about authenticated key exchanges. But at some point I'm no longer providing simple "right answers" and instead am writing a half-assed book on modern crypto that I'm not qualified to offer.

The more important bit here is that I was updating Colin Percival's recommendations, which didn't include a KDF or an AKE. :)

I'm surprised to see so few recommendations for libsodium. https://download.libsodium.org/doc/

For pretty much any crypto task that a "run-of-the-mill programmer" is likely to run into, they've got you covered.

Secret key encryption: https://download.libsodium.org/doc/secret-key_cryptography/a...

Password hashing: https://download.libsodium.org/doc/password_hashing/

I would go for TweetNaCl instead.

The problem I have with most of the crypto libraries is that their attack surface is absolutely enormous.

Most people don't need SSL. Most people don't need a zillion choices.

Most people need a single choice that actually works and is resistant to programmer error.

Isn't the attack surface limited to the methods used in the application though? Even if libsodium has a vulnerability in some ABC method, unless the application in question uses that code path, it's not an immediate risk (Obviously it should get patched and stable, secure software is preferred over the alternative). I'm just trying to understand how the "attack surface" is calculated, and how a potential vuln in an unused method is a huge risk.

> Isn't the attack surface limited to the methods used in the application though?

No, because the combination of how you put them together can make you vulnerable.

For example, if you are encrypting lots of messages that all have the same header, certain crypto algorithms can be made to leak the key.

Do you know which combinations those are? I sure don't by default.

The fact that an end programmer even has to think about this is the problem.

In any cryptosystem, the application programmer is the person who knows the least about crypto. If he has to make any decision, you can expect he will get it wrong.

Good points. I was about to say something about how libsodium will take care of most of that for you.

For example, I thought they provided some facility for avoiding nonce reuse vulnerabilities by automatically generating pseudorandom nonces for the user.

But then I double checked their API docs and they don't do this at all! Argh!

Look into the history of OpenSSL vulns -- many are in obscure TLS paths that application developers did not intend to be supporting.

I think Heartbleed's even an example? Apparently there's some TLS ping ("heartbeat") command in the protocol that I'm pretty sure no-one actually asked for or uses in their applications, but there it is in the code, and so you're vulnerable as an application author.

That's a different kind of thing—TLS is an extensible protocol, where its various extensions (i.e. code paths) are activated by patterns of data on the wire. libsodium is just a set of components—you can know at compile time exactly which functions in libsodium will or will not ever be called by your program, and can, if you like, use a linker that does LTO to prune the majority of the library out.

Cryptography Engineering [0] is a great book that covers key topics in cryptography with a focus on best practices for implementors and system/protocol designers.

Matthew Green's blog, A Few Thoughts on Cryptographic Engineering [1], has a wealth of interesting posts that are often aimed at explaining cryptography to a "technical but non-cryptographer" audience, and tend to be motivated by recent events in security/cryptography news.

[0]: https://www.amazon.com/Cryptography-Engineering-Principles-P... [1]: https://blog.cryptographyengineering.com/

The IT Security StackExchange website contains lots of information which is generally kept reasonably up to date. For example a TLS answer might be a bit old and not list last week's attack, but if something turns incorrect it will often be edited.


OWASP has some nice guidelines on a lot of topics, including storing passwords.

Start at https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet

OWASP's cryptography advice is almost invariably awful, and that password storage thing is among the worst of it. It's better now than it was when it recommended against password hashes (note that it still recommends "cryptographically strong salts") but remains factually incorrect in more than one place, including the notion that PBKDF2 is better than bcrypt (the opposite is true).

Agree that OWASP's crypto advice is generally garbage, but is there a better salt policy than what they have?

    [protected form] = [salt] + protect([protection func], [salt] + [credential]);

I assume tptacek's objection is that salts need to be unique (at most, unpredictable enough to discourage precomputation), and don't need to be produced by a CSPRNG.

Edit: or maybe something else from the editorial history of the document?

There's that, but more generally and importantly, application developers who take special measures to generate salts tend not to be using secure password hashing algorithms --- the libraries for things like bcrypt tend to handle this for you.

Maybe akin to the "typing the letters A-E-S" in https://www.nccgroup.trust/us/about-us/newsroom-and-events/b...?

"Just use bcrypt" (or scrypt). Salting is baked in.

Agree with this, except I often find OWASP hard to navigate or know what's still relevant. Plenty of old projects linger about. They try to flag projects but still troubling.

The answers for this depend on what you're trying to do. Can you be more specific? Coda's password storage advice is still the best advice for people who don't know what they'd do otherwise.

I'm currently building a community website for these kind of questions (storing password, constant-time token comparison), the design is pretty raw for the moment: https://sqreen.github.io/DevelopersSecurityBestPractices/saf...

The code examples are in Python, but I plan to add pages in other languages.

The golden rule about storing a password is to not store a password... I can't wait till SQRL takes off

It won't. See http://security.blogoverflow.com/2013/10/debunking-sqrl/ for a myriad of reasons.

I've also come to realize that one should take everything that SG says with a large table spoon of salt.

> The proposed SQRL scheme derives all application specific keys from a single master key. This essentially provides a single juicy target for attackers to go after.

That sounds like the same problem password managers have. And yet they are still recommended over (re-)using your own passwords for each website.

The crucial difference is that with a password manager, passwords are protected by a master key, but not derived from it. So you can rotate passwords whenever you want, either proactively or reactively, mitigating the effects of a password database compromise.

Note the protocol has been improved since then, for example by adding revocation features.

Why is that? I've heard lots of people saying that, but not had any concrete reasons why. As far as I know, he's generally correct about the things he discusses. And pretty good at making technical discussions interesting.


Steve has been on public record for at least the past 12 years weekly on Security Now explaining things clearly and carefully. I've learned a lot from him and am very thankful.

If he even makes a tiny mistake on a podcast episode about something he comes back with a correction the next week.

He's been sharing his knowledge and expertise generously and a lot of people like me enjoy listening to him for 2 hours every week.

If you have a criticism write it out properly.

Yeah, I've seen that site - 1 item in the last 10 years. Not a lot considering that he broadcasts 2 hrs a week. Maybe he's improved since the early 2000s?

Anything else? I don't really understand the extreme reaction he seems to get.

Is that at all likely? Looks like SQRL was published in 2013... and this is the first I've heard of it.

No, it is not at all likely.

I argue that one-time password with a secure MFA implementation is essentially the best viable solution.

Dan Boneh's Coursera course is ideal for any beginner. Cryptography Engineering by Schneier et al. is good, as is Ross Anderson's Security Engineering, but both are fairly dated.

The OWASP guidance is OK for a quick access to best practices, but insufficient for rigorous learning.

Cryptography takes time to digest the fundamentals and recognise how new concepts are both beneficial and, vitally, disadvantageous; sadly, there is no cheat sheet or quick fix.

Source: computer security PhD student.

Quick sites:

* PyCon Crypto 101 - https://www.crypto101.io/ (and if you use Python, please use Cryptography library for encryption/decryption please, Python built-in provides sha and hmac already though, and please adopt your framework's security implementation whenever possible).

* Mozilla Web Security Guidelines - https://wiki.mozilla.org/Security/Guidelines/Web_Security

* Mozilla Secure Coding Guideline - https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines

* Mozilla Server Side TLS - https://wiki.mozilla.org/Security/Server_Side_TLS

* Mozilla Intro to Cryptography (slide: https://april.github.io/crypto-presentation video: https://www.youtube.com/watch?v=bg32spD2mB0)

* Mozilla Web wiki - https://developer.mozilla.org/en-US/docs/Web (understand CORS, Cookies, CSP, etc)

* Google's course on security - https://google-gruyere.appspot.com/ (original course page has been taken down by Google already)

Book recommendations:

* The Web Application Hacker's Handbook

* The Tangled Web: A Guide to Securing Modern Web Applications (written by the famous Michał Zalewski working at Google, and lately known for developing the American Fuzzy Loop AFL which has been used for uncovering many new CVE bugs).

* Hacking: The Next Generation

* Securing DevOps (to be released soon)


* USENIX - https://www.usenix.org/ (tons of free high quality conference talks, I like USENIX over ACM)

* Real World Crypto

Getting real

* Go find bug bounty program out there, many well-written posts how one discovered bugs

* Follow a bunch of security engineers / security-minded folks on Twitter (e.g. @matthew_d_green would be a good start)

OWASP is a great reference, you read it as an index page. But like others have pointed out, the Wiki is often outdated, but concepts almost always remain the same. Use multiple resources before implementing a solution, and never just copy and paste solution posted by others on Stackoverflow. Sorry for so many Mozilla stuff definitely there's some bias from me but I trust folks running the sec team there.

A good guide for password hashing is https://paragonie.com/blog/2016/02/how-safely-store-password... . I think your codehale link is out of date since it's from 2010.

Not bad, but I found this questionable:

> The other Password Hashing Competition finalists (Catena, Lyra2, Makwa, and yescrypt)

These were promoted above PBKDF2; algorithms with few implementations. PBKDF2-HMAC-SHA-512 with sufficient iterations is typically robust, and has been scrutinized.

I personally prefer scrypt, but in lieu of a solid scrypt or bcrypt lib I wouldn't hesitate to lean on PBKDF2 over the others.

Argon2i was in the same boat but being in libsodium went a long way to reinforcing trust, although Argon2i and Argon2d should really have had distinct names.

The page gives solid rationale against PBKDF2:

Although PBKDF2 is more widely available than bcrypt or scrypt, it doesn't offer the GPU resistance that we need from a password hashing function. If you must use PBKDF2, make sure you use at least 100,000 iterations and a SHA2 family hash function.

To reiterate: PBKDF2 can still be secure. It's the least secure of the acceptable password hashing algorithms on this page, so we aren't going to provide any example code.

I made this a while ago: http://howtostoreapassword.com. Still relevant I think. :)

I should probably update it to use one of the more modern algos, but the availability of good bcrypt libraries makes it solid advice still.

That was pretty comical. I don't know if it is just my connection but it seems to take a pretty long time to load a page with a relatively small amount of content.

Not necessarily best practices, but I recommend the Matasano Crypto Challenges to basically everyone. I make all of the developers on our team do them too:


Those challenges teach vulnerabilities in old, low level cryptographic primitives. As much as I enjoyed those challenges, they are not a good place to start for a developer trying to build a secure application.

Low level, yes. But, old? We cover AES, HMAC, stream ciphers, GCM, RSA, DH, SRP, and elliptic curves. The criteria for inclusion on the first 6 sets of challenges was "had to be something we took advantage of on the job at Matasano". It's not textbook stuff.

Part of the point of the crypto challenges was to illustrate why people shouldn't work directly with low-level primitives, as a sort of antidote to the kind of advice OWASP gave out.

The first set of problems are all very simple, but you have to start somewhere.

I'm not sure that the cryptopals chalelnges are the best way to learn exactly how you should be implementing everything, but I've found the knowledge that I gained from doing the challenges very applicable in my daily job and definitely helped further my understanding of crypto in a way that reading a book just couldn't do.

Part of the point that I got with cryptopals is how easy it is to break stuff that you thought was hard to break.

There is a theory that we practice on my team that you don't really understand something unless you try to break it. And this team regularly tells developers facts about their programs and systems that previously unknown to them.

I don't know much about how a developer should try to build a secure application from the get-go. I don't think I've ever worked on or assessed a codebase where that plan worked.

I did the challenges years ago when you had to email in for them. Since then I can count at least five occasions where having done the challenges has allowed me to identify vulnerabilities in real-world crypto. I was usually able to recommend fixes that in theory made those codebases more secure. This is keeping in mind that I'm at best a hobbyist security researcher and just barely a professional developer.

I think there are about seven or eight people on Earth that I would trust to securely implement cryptography in their code. For the rest of us I'm happy with doing the best we can with libraries that make that easy (NaCl), and otherwise trying to find ways to break the thing. The cryptopals challenges help you do that, so that's where I'd recommend a developer start.

So, what's the recommendation for an Authenticated Key Exchange?

I see a lot of "don't use" but I don't see any "do use" for that case.

May be on a tangent and a shameless plug, but I just posted https://news.ycombinator.com/item?id=14042150 this morning.

Underlock is a small Ruby library that helps with Encrypting/Decrypting of files and other data.

Unfortunately, I think libsodium remains a categorically better answer for this problem.

FYI I think you're getting downvoted because NIST is known to have recommended a pseudo-random number generation algorithm that is believed to have been intentionally designed with a backdoor [1], presumably by some US 3 letter agency.

OWASP seems like a decent source for learning about security topics at a high level (particularly web app security).


I didn't follow that discussion closely, so I will avoid the argument here on that subject. Overall, NIST is a good resource for comparison. If you work with government, enterprise security, or compliance, you want to go through NIST. If you have spare time I recommend read https://beta.csrc.nist.gov/publications.

NIST is also responsible for running https://nvd.nist.gov/ which is a great asset for finding CVE.

I agree. They got subverted at one point by an organization they thought was helping them. Their overall catalog of advice is OK in that it's a lot of the stuff readers would hear from people they paid for IT or INFOSEC advice. Just free instead. A good example are the recommendations in this one for small, business owners that don't know anything about INFOSEC:


DISA has the "STIG's" for security configuration:


The NSA themselves, the Information Assurance Directorate, had guides on hardening various things. There's one for deploying Chrome in the link below that also references STIG on Chrome:


It would be straight-forward for INFOSEC people to vet the NIST or STIG guides for content accuracy then host that copy on their own sites. Or produce similar guides as some do. Just important to target them at people of low knowledge or competence so they know exactly what they need to do. It's them whose hardware will become part of the next DDOS due to configuration error.

> They got subverted at one point by an organization they thought was helping them.

Fair points, shouldn't throw the baby out with the bathwater etc. But as a governmental agency, do they have the autonomy to avoid being similarly subverted in the future? Not rhetorical, I genuinely don't know how they are governed/if they can refuse the "help" of the 3 letter agencies.

Which makes me realize, the 3 letter agencies may have still benefitted by the Dual_EC_DRBG scandal coming to light - what they lost in a backdoor, they gained in a chilling effect on the spread of good crypto practices by staining NIST's reputation.

"do they have the autonomy to avoid being similarly subverted in the future? Not rhetorical, I genuinely don't know how they are governed/if they can refuse the "help" of the 3 letter agencies."

It could happen to anyone if it's about receiving bad advice from an authority with a conflict of interest. That's why the solution is to either produce good advice for each of the things they're talking about or vet their advice to see if it contains any problems.

"what they lost in a backdoor, they gained in a chilling effect on the spread of good crypto practices by staining NIST's reputation."

I never thought about that. I doubt they intended that but it might be a real benefit for SIGINT side. That's interesting enough angle I'm going to bring it up to regulars on Schneier's blog who discussed the NIST stuff a lot.

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