Cryptographic Right Answers
gist.github.com
gist.github.com
Note that "SHA-512/256" is a separate algorithm, not to be confused with "SHA-512 or SHA-256" which are two other less secure algorithms.
http://en.wikipedia.org/wiki/Length_extension_attack http://cryptopals.com/sets/4/challenges/29/
I have to say it feels a bit weird to deduct points (so to speak) from a highly regarded cryptographic hash function because it doesn't outright prevent one particular, broken MAC generation scheme, but I guess the argument has some merit.
While I think it's harmless to say that SHA-512/256 is stronger than SHA-256 (as they otherwise provide the same theoretical level of security), I still think it's wrong to claim that SHA-512/256 is also stronger than SHA-512, which has a vastly greater theoretical security margin.
Just use a MAC algorithm that isn't terrible.
The "security margin" of a full SHA2-512 digest, over its truncated SHA2-512/256 alternative, is not meaningful in practice.
If you want to use full-width SHA2-512, go ahead. SHA2-512/256 is safer.
What's the reason to prefer scrypt over bcrypt? And, what's the reason to prefer both over PBKDF2? (Asking because I see quite a few bits of software that use PBKDF2.)
> Asymmetric signatures (Was: Use RSASSA-PSS with SHA256 then MGF1+SHA256 yabble babble): Use Nacl, Ed25519, or RFC6979.
Could you make a recommendation for or against using GPG, since that's by far the most common approach for asymmetric signatures? (Obviously such a recommendation would need to point at specific key/algorithm choices to use or avoid.)
> Client-server application security (Was: ship RSA keys and do custom RSA protocol) Use TLS.
Using which of the many TLS implementations?
scrypt is asymptotically much more expensive to crack.
And, what's the reason to prefer both over PBKDF2?
scrypt is asymptotically much more expensive to crack.
bcrypt is asymptotically marginally more expensive to crack than PBKDF2, but not enough to matter; I'm guessing tptacek's point here is that bcrypt has more library support available (despite PBKDF2 being the de jure standard). I wouldn't say there's a strong argument in either direction.
Could you make a recommendation for or against using GPG, since that's by far the most common approach for asymmetric signatures?
Avoid if possible. The code was written by a colony of drunk monkeys, in an era before anyone understood the basics of modern cryptography; I'm really not sure which is worse between gnupg and OpenSSL. Of course, GPG is the standard for encrypted email, just like SSL/TLS is the standard for web sites, so you may have no choice...
> Avoid if possible. The code was written by a colony of drunk monkeys, in an era before anyone understood the basics of modern cryptography; I'm really not sure which is worse between gnupg and OpenSSL. Of course, GPG is the standard for encrypted email, just like SSL/TLS is the standard for web sites, so you may have no choice...
Do you have any recommendations for high-level alternative for GPG, i.e. something that can secure data easily at rest. Is there something that wraps e.g. NaCL with file IO in a nice commandline utility?
At work we are occasionally using 7zips encryption ability, but somehow I don't really have high confidence in it. But at least the UI is simple enough.
Are there any viable FOSS implementations of the OpenPGP standard other than GPG? Detached GPG signatures seem to be the most common mechanism to validate software distribution and similar.
How so? The cost of password cracking generally scales completely linearly, is there an attack on bcrypt that makes the cost sublinear? I would agree that scrypt probably has a better constant factor on typical hardware.
If using GPG means you can delegate away all your crypto design, use GPG. What you should not do is roll your own by co-opting all of GPG's design decisions, some of which are not great.
You should use BoringSLL, LibreSSL, Go crypto/tls, or OpenSSL, in roughly that order.
Can you elaborate on what you mean by "nice properties"?
> If using GPG means you can delegate away all your crypto design, use GPG.
Using which key types, ciphers, etc? The most common recommendation seems to be for 4096R keys and SHA2 hashes; the latter is consistent with the recommendations posted here, but the former seems to disagree with the comment to not use RSA for asymmetric crypto.
Anyway, I don't get your (as in most security experts) aversion to long keys and multiple algorithms. As an engineer, I see cryptography taking a very small amount of the resources, but holding a huge share of the risk of any security application. My guts are always pointing into moving more resources into crypto.
I guess bcrypt is harder by default than PBKDF2
Makes sense, thanks.
> I guess bcrypt is harder by default than PBKDF2
Does that imply that software using PBKDF2 is equally safe if it turns up the difficulty?
On a slightly related note, I just noticed that there is also µNaCL for embedded use that seems really cool.
Nacl isn't an open source project or helpmate for application programmers; it's an academic effort to design the best misuse-resistant crypto interface for programmers. I like libsodium, but it is not that.
Should we prefer curve25519 from NaCL but stick with the finalized ed25519 construction for signatures and long term compatibility?
I got a serious chuckle out of this. :)
I realize that the library is probably available via my package manager, but it'd be nice if the install page (http://nacl.cr.yp.to/install.html) linked to an archive over HTTPS and had some signatures to compare hosted elsewhere.
So when I have AAD, what should I do when using NaCl? Add it as part of the message to crypto_secretbox(), or should I authenticate this data separately?
https://download.libsodium.org/doc/secret-key_cryptography/a...
Eg: > Avoid: AES-CBC, AES-CTR by itself, block ciphers with 64-bit blocks --- most especially Blowfish, which is inexplicably popular, OFB mode. Don't ever use RC4, which is comically broken.
Why not 64-bit blocks? What's wrong with them? How do they affect us?
Mind you, I'm not saying the statement is incorrect, but with no justification for it, I'm not convinced why I should avoid them.
The right way to learn about cryptography is to start by learning how to break it. If that's something you're willing to sink time into, try this thing we set up:
It's totally free and by the send of set 3, you'll have an appreciation for block sizes.
For people on larger teams, or working next to teams of developers, "use X not Y" will lead to pushback of "why not?" and full answers will be needed.
Okay, very glad to hear that there's still work being done on that end. I'll start sending solutions in then :3
But I always thought that Crypto Pals was a Matasano project. He should know if someone took up the mantle in his absence.
If you're feeding effectively random data into the block cipher (like if you're using CBC), then because of the birthday paradox, you get at most about 2^32 blocks (far fewer in practice at a good security level) per key if you have 64-bit blocks. This is low enough to be annoying for designers or problematic for suites that don't rekey correctly.
However, because CTR (or GCM) mode uses sequential inputs to the cipher, I think that a 64-bit block size would not be a problem there. At that point, the reason not to use 64-bit block ciphers is because they're all older, weaker, and less-supported than AES-128.
AES-GCM
As tptacek says, this has pitfalls on some platforms. I also dislike exposing AES cores to malicious data, which is my primary reason for preferring a hash-based MAC construction.
Avoid: key sizes under 128 bits.
My recommendation for 256-bit symmetric keys isn't because I think AES-128 can be broken mathematically; rather, it's because AES implementations have a history of leaking some of their key bits via side channels. This is less of an issue now than it was five years ago (implementors have found and closed some side channels, and hardware AES implementations theoretically shouldn't have any) but given the history of leaking key bits I'd prefer to have a few to spare.
Avoid: userspace random number generators
Thomas and I have argued about this at length; suffice to say that, as someone who has seen interesting misbehaviours from kernel RNGs I'd prefer to use them for seeding and then generate further bits from a uesrspace RNG. (Thomas's counterargument, which has some validity, is that he has seen interesting misbehaviours from userspace RNGs. This largely comes down to a question of whether you think the person writing your userland crypto code is more or less prone to making mistakes than the average kernel developer.)
avoid RSA
Thomas is correct to imply that a random RSA implementation is more likely to be broken than an average elliptic curve implementation. This is true for the same reason as a random program written in python is more likely to have bugs than a random program written in Brainfuck: Inexperienced developers usually don't even try hard problems. On the other hand, for any particular developer, an RSA implementation they write is more likely to be correct than an elliptic curve implementation they write.
I also continue to be wary of mathematical breakthroughs concerning elliptic curves. Depending on the amount of new research we see in the next few years I might be comfortable recommending ECC some time between 2020 and 2025.
use NaCl
This is not entirely a bad idea. The question of "implement yourself or use existing libraries" comes down to the availability of libraries and whether the authors of the library are more or less prone to making errors than you; "random developer vs. NaCl developers" is straightforward and doesn't have the same answer as "random developer vs. OpenSSL developers".
you discover that you made a mistake and your protocol had virtually no security. That happened to Colin
Just to clarify this, the (very embarrassing) bug Thomas is referring to was in the at-rest crypto, not the encrypted client-server transport layer.
Online backups (Was: Use Tarsnap): Remains Tarsnap. What can I say? This recommendation stood the test of time.
I have to agree with Thomas on this one. ;-)
* The track record of userspace RNGs vs. kernel RNGs speaks pretty loudly. In any case, we should be clear that you're advocating for "bootstrap with /dev/urandom and then expand in-process", not, like, havaged or dakarand. We're closer on this than people think.
* I'm not even talking about people writing their own RSA. Do I need to say that? If so, recommendation #1: don't write your own RSA. I'm saying that all else equal, if you're using good libraries, still avoid RSA, for the reasons I listed.
* In fairness, the CTR problem you had is also a threat to GCM. This used to be why I recommended CBC a few years ago: because we kept finding gameover CTR bugs in client code, and not so often CBC bugs. My opinion on this has changed completely in the last year or so.
Right. And I'm optimistic about Salcha20 and Poly1305, but I'd like to see a few more years of people attacking them before I would be willing to recommend them.
we should be clear that you're advocating for "bootstrap with /dev/urandom and then expand in-process"
Right. Or to be even more precise: Use HMAC_DRBG with entropy_input coming from /dev/urandom.
Also: For $DIETY's sake, if you can't read /dev/urandom, exit with an error message. Don't try to fall back to reading garbage from the stack, hashing the time and pid, or any other not-even-remotely-secure tricks. Denial of service is strictly superior to falsely pretending to be secure in almost all conceivable scenarios.
I'm interested to hear the rationale behind this. Those seem like reasonable options considering OpenSSL's (and their) security history.
Bugs happen to everyone, but the process that led to this one is really concerning. (OpenSSL certainly has bad process too but as the GP mentions, more people are hammering on it.)
This blog post has more (including an LWN article about it):
http://gehrcke.de/2014/03/gnutls-vulnerability-is-unit-testi...
Your recommendation for TLS elsewhere in the thread was:
> You should use BoringSLL, LibreSSL, Go crypto/tls, or OpenSSL, in roughly that order.
Three of those are based on OpenSSL, and Go crypto/tls presumably only works with Go.
Sorry.
My experience with their software has been very positive, and they have avoided the majority of recent insecurities. Plus they have great support for anyone working on open source projects.
But then, they use it on the client side, and I have no idea if that makes any difference.
Can anyone please explain what's wrong with e.g. 4096 bit keys (instead of 1024 bit) and piling 2-3 different or same encryption passes? Performance implications are obvious; what are security implications?
I get a whole bunch of links about javax.xml.crypto.dsig throwing exceptions, which wasn't terribly illuminating.
I think the reference is to the bugs discussed on page 21 here: http://www.contextis.com/documents/33/Exploiting_XML_Digital... but I'm not sure.
Make sure the data fed to your MAC is unambiguous. Or rather, make sure the data fed to your MAC is done in such a way that you cannot have different messages appear the same to the MAC encoder.
For instance, say you sort and concatenate your options without a delimiter. Then ["ab", "cd"] will have the same MAC as ["a", "bcd"], as in both cases the actual data fed to the MAC will be "abcd". This is a very bad thing.
http://www.daemonology.net/blog/2008-12-18-AWS-signature-ver...
I don't want authentication here - there's no way for me to manage these keys; I just want to prevent someone from reading my logs off the disk...
But I'm not sure you completely thought this out. If somebody can read your disk, and if that includes software configuration, the only way to make it impossible for people to read your logs is by using asymmetric crypto. And yes, that'll require using different keys on the writing and reading software.
You care about this if: you need to encrypt the same kind of message to many different people, some of them strangers, and they need to be able to accept the message asynchronously, like it was store-and-forward email, and then decrypt it offline. It's a pretty narrow use case."
Is this like bitmessage?
For each key you use, pick 1 format of messages for it to authenticate. Document that format. Version-control that documentation along with the code that uses it. If the format changes in a non-back-compat way, pick a new key (so try to use a backwards-compatible format). Ensure the documented messages make sense (try not to have a "fire this person" message without knowing who is that person) - timestamps and/or nonces can really help here.
If you can't pick just 1 format, you can say have the first 16 bytes of the message be a UUID, and document each UUID-format (with the same documentation rules as if you are not using a UUID).
Seriously, that and "don't mix secret and unauthenticated things" together covers 90% of all vulnerabilities.
NaCl/libSodium provide higher level interfaces where the underlying primitives are removed from the developer which makes it much more difficult to implement bad crypto (at least as far as the individual constructs go...protocol design may still get you)
But still feels odd OP is sharing it since it was a secret link.
Or, more than likely, he had it as "secret" to get feedback from colleagues and other crypto folks before he published it.
I occasionally use it to make /dev/random unblock for applications that think they need to use /dev/random to generate keys (cough gpg cough).
Are there any recommended schemes for password-authenticated key exchange?
In my opinion one should create encrypted channel essentially without any authentication and then do authentication inside of such channel, with ZKPP being one of the interesting ways of how to do that (with "plug password into scrypt and use the result as EdDSA secret key" being particularly straightforward solution), which obviously assumes that you have threat model where exposing password to server is meaningful security concern (usually it is not).
I've seen many systems where ZKPP is the right thing to do (such systems usually involve offline operation with multiple users using same device), but their authors came up with some weird-ass construction with bunch of symmetric primitives that is anything but secure.
"Avoid cipher cascades." I've pushed and successfully used cascades in highly assured work for years. Cryptographers talk down about it but "meet in the middle" is best attack they can cite. So, they're full of it & anyone who cascaded might have avoided many algorithm/mode breaks. My polymorphic cipher works as follows: three strong algorithms applied out of almost 10 potentials; algorithms are randomly selected with exception that each pass is a new algorithm; separate keys; separate, initial, counter values; process driven by a large, shared secret. Breaking it without the secret requires breaking all three and no cryptographer has proven otherwise despite massive speculation.
I'll briefly mention scrypt because it's ironically great advice. I asked cryptographers for over a decade to deliver a slow-by-design hash function that couldn't be sped up. They, for years on end, criticized me (see Schneier's blog comments) saying it was foolish and we just need to iterate a fast one. I expected problems and hackers delivered them. I had to homebrew a cryptosystem that input a regular HMAC scheme into another scheme: (a) generated a large, random array in memory, (b) did impossible to speed up operations on random parts of it, (c) iterated that excessively, and (d) finished with a proper HMAC. Array size always higher than GPU or FPGA onboard memory in case opponents used them. Eventually in a discussion, a Schneier commenter told me about scrypt and I finally got to ditch the inefficient homebrew. A true outlier in the crypto field.
Avoid RSA: bad advice for commercial if NSA is opponent. All his risks are true. NaCl is great and my default recommendation. Yet, he doesn't mention that NSA has another reason for pushing ECC: they own 26 patents on it that they license conditionally on the implementation details along with ability to restrict export. We know what NSA's goal for crypto is and therefore I avoid ECC commercially like the plague. I just used RSA implementations and constructions pre-made by experts with review by experts. Esp GPG, as NSA haven't even broken it. They use it internally, actually.
For asymmetric signatures, see above. All points apply. I'll just add that, for post-quantum, there's been tremendous process in Merkle signatures with things such as unlimited signatures. Their security just depends on a hash function, there's no known quantum attacks on them, and they're doing pretty good against classical attacks, too. So, I'm following and doing private R&D on standardizing Merkle signatures plus hardware to accelerate it on either end.
He says use OpenSSL and avoid MatrixSSL, PolarSSL, etc. He said some vague stuff about their quality. Problem: anyone following the git comments of OpenBSD team that tore through OpenSSL knows that IT WAS S*. It was about the worst quality code they've run into with so much complexity and potential to be exploited that the NSA would be proud of it. I'd be surprised if Matrix, Polar, etc are worse and less structured than that. If OpenSSL is really the best, then we're in a bad situation and need to fund a clean-slate design by experts like Galois and Altran-Praxis.
Although I'm focused on problematic points, his last piece of advice deserves special mention: use TLS. These protocols have proven difficult to implement properly. TLS and their ilk have had many problems along with massive effort to smash them. Against that backdrop, it's actually done pretty well and using it like he suggests is best option for COTS security. Medium to high assurance systems can always use variants custom-designed for that level. Most don't need that, though.
But my concerns aren't about code quality. They're cryptographic.
- Use OpenSSL with TLSv1.2 for TLS
- Use Tarsnap for online backups
- Use NaCl for anyhing else
- Try not to use anything new that you invent before it's reviewed
- What about the correct password length ?
Then again, it cracks me up that Microsoft have https at all, given the protocol checks https and http when it goes to lyncdiscover.domainname
256-bit random identifiers are overkill. 122 random bits (as in a GUID) should still be more than sufficient. Size is important for IDs because people whine about the storage overhead. A 256-bit identifier requirement may unfortunately convince some people that it's better to use much smaller, non-random identifiers, and that'd be a shame.
GUIDs are unique--not necessarily unguessable. Any implementation may be using a CSPRNG but in general you shouldn't rely on that (unless its your implementation and its a documented behaviour.)
Honestly I've found this (perhaps pedantic) mistake to be highly correlated with other badness/sloppiness.
GUIDs are awesome, and can be used in plenty of places near crypto, like OAuth 1.0-style nonces, IDs for public keys... just don't use them for their "randomness".
But anyway, my point wasn't that you should necessarily use GUIDs for unguessable IDs (although that's fine if you're using real randomness), but that 256 bits is overkill and that 128-ish is good enough.