Openssl: uses only 32 bytes (256 bit) for key generation
bugs.debian.org
bugs.debian.org
OpenSSL doesn't always retrieve all its random bytes from urandom; it seeds its own local PRNG with urandom, and feeds raw random bytes from its own state.
There are no simple answers in public key crypto: the idea that you only need 256 bits of random data can blow your head off if you use something other than RSA. For instance, if you fill only some of the bits of a DSA k value, attackers can extract your private key from a series of public signatures.
Some of the comments on that bug thread are batty, though. The OpenSSL CLI tool doesn't implement its own randomness or key generation; it's a CLI wrapper around the core OpenSSL functions. The CLI might be for "debugging purposes" (but obviously not really, since most instructions for generating SSL certificates involve using that CLI), but the core routines surely aren't.
You start with two random primes. Generally to generate these what you do is pick a range of numbers in the right size, then test the odd ones with a prime sieve (vs small primes), then do probabilistic primality test on the winners. This doesn't need 4096 bits of randomness.
Once you have the primes, you don't need any more random numbers to generate the key; it's purely deterministic calculation at that point.
This seems to be expected behaviour for generating RSA keys. An RSA key of length 4096b does not provide you with a security level of 4096b. That is, you don't have to straight-up guess the keys, you work at it via factorisation.
The issue is arising from the fact that entopy and key length are both commonly measured in bits. The entropy of an RSA key is much lower than the key length. 256b of entropy seems to be more than reasonable at first glance.
Normally, I would not defend openSSL, but I will do so here, having not even looked at the responsible code (nor has the submitter of this bug), and not even looked at the mailing list link.
Seriously, do not panic, let the cryptographers look at this and decide if it's really an issue. It's probably good that they're getting 256b of entropy from urandom, it's likely that they're seeding a CSPRNG for prime generation & testing.
I would wager some small sum on this being closed by the end of the week, and us looking back on this and shaking our heads at the uninformed knee-jerk reaction of people in here:
"If I ask for a 4096-bit key, I should get one, or an error message. I shouldn't get a 256-bit key that looks like a 4096-bit key." -- taejo, 15 minutes ago
>Historically, the OpenSSL command line tools have been intended for debugging only.
My answer would be the exact same as you quoted, the openssl cli tools are quite horrendous to use and you certainly wouldn't use them if you were a CA. If you are a CA or deal with certificates, openssl does provide sweet inspection dumping tools for asn1 and certs.
If you have an application which generates keys or certificates, why would you system exec openssl cli when your language of choice has a Crypto implementation, or glue to OpenSSL.
So I ask openly, run `history | grep openssl` and see. Even running `openssl help` is daunting unless you're familiar with most symmetric block modes.
openssl s_client -connect <hostname>:<port>
Also for conversion of certificates to different formats and removing passphrases from existing certificates.A random comment by one Debian developer do not constitute the position of the Debian project. On top of that, consider the subsequent comment that the information in question came from an OpenSSL developer.
The 32 bytes it gets goes back into a similar CSPRNG as the CSPRNG it came out of.
So instead of requesting 4096 bits from a CSPRNG, it requests 256 bits from a CSPRNG and uses that to initialize another CSPRNG which it reads 4096 bits from. Cryptographically speaking it's the exact same thing.
The question to be asking is whether the output from either CSPRNG is predictable.
> debugging only.
That very much surprises me. Can someone explain, elaborate, or source this idea?
Obviously the tools are useful for debugging purposes, testing tls connections, dumping cert information and asn1.
I've now been made aware that tools wrap the openssl cli instead of using it's programmatic API.
Once I tried to use the ca functions of the tool, found the whole tool entirely too cumbersome and wrote my own using libopenssl.
What do you use it for extensively if I might ask?
>Historically, the OpenSSL command line tools have been intended for debugging only.
This seems rather out-of-touch with reality.
1. Put the random number in that state
2. Use that randomness to build a RSA key pair
3. Do an RSA decryption of the captured key exchange using this key
4. See if the symmetric key we get decrypts into sensible plaintext
The thing to note is that steps 2 and 3 are both expensive -- especially step 2. This isn't nearly as easy as scanning a 64-bit key on a symmetric cipher! So suppose for a second that you've got a huge data center full of machines at your disposal and you can do a billion tests per second -- a full sweep of the 64-bit space would still take 584 years. So you better hope you'd get lucky.Now would that be enough protection? Of course not -- computers get faster, and a determined enough adversary could build special hardware. (Although, again, it would be orders of magnitude more complicated than just SHA-512 bruteforcing)
The point I was trying to make is that even if they were somehow only using 64 bits of entropy, a practical attack would still be difficult to mount. I'd say that each test would be at least 2^16 times more computation than a typical symmetric cipher check. Therefore I think it would be about as hard as bruteforcing a 80-bit symmetric key.
In other words, 256 is way more than plenty.
The "256 bits" (in this case) are used as a seed for the OpenSSL CSPRNG.
OpenSSL's RSA generation asks for two prime numbers each (bitlen/2) long. OpenSSL's primegen works by iterating over random numbers, here each (bitlen/2) long (of which (bitlen/2-2) are random), looking for primes.
As for the strength of 256 bits, the Wikipedia page on brute force attacks should tell you how infeasible attacking even a 128 bit key is: http://en.wikipedia.org/wiki/Brute-force_attack
The remaining questions are
1. Is openssl(1) really only intended for "debugging purposes"?
2. http://www.philandstuff.com/2013/03/14/why-does-gpg-need-so-...
This quote in particular struck me as very strange.
> From: Florian Weimer <fw@deneb.enyo.de>
> To: Thorsten Glaser <tg@mirbsd.de>
> Cc: 742145@bugs.debian.org
> Subject: Re: openssl: uses only 32 bytes (256 bit) for key generation
> Date: Wed, 19 Mar 2014 21:33:10 +0100
>
> * Thorsten Glaser:
>
> >>Historically, the OpenSSL command line tools have been intended for
> >>debugging only.
> >
> > I disagree,
>
> It's what I was told by the OpenSSL developers.
>
> > Also, what do other tools (that do not invoke openssl(1)
> > unlike most of these I saw, which were shell wrappers
> > around it) do, entropy-wise?
>
> There are different choices. Some use more bits from /dev/urandom,
> some even block on /dev/random. The latter is quite problematic for
> non-interactive key generation during package isntallation.
1. I would doubt most actually block on /dev/random, but why? /dev/urandom should be Good Enough For Everyone, except in very narrow circumstances. But why isn't someone with a firm grasp of crypto setting a safe default? Why are implementers and consumers of these components making these choices of entropy size ("some use more bits") and underlying sources ("some even block..."). This is ridiculous, I don't trust the average developer to make safe choices in this respect. Why is it okay? This is incoherent. Either OpenSSL has safe defaults, or it doesn't. Leaving it up to consumers to do it correctly is giving up - and leads me to believe it's done unsafely by default.
2. The inconsistency alluded to by referring to non-interactive key generation and "some even block on" startles me. I don't know why developers think blocking on key generation is generally safer, but if they do, why are other (perhaps the same?) developers sacrificing that safety when generating keys on package installation for the sake of user experience? If /dev/random is safer, it should be used, and if not, it shouldn't be (because of the blocking issue.) The lack of guidance from crypto-savvy developers is deeply concerning.
Numbers can't be more or less random, either both are unsafe, or both work. Both use exactly the same algorithms (on Linux) to generate numbers, and the numbers come from the same pool.
More in depth analysis: http://www.2uo.de/myths-about-urandom/
If this is true, then /dev/urandom might split out unsafe bits (as unlikely it is), which to me sounds like a terrible idea when creating a key or similar very importants secrets.
CSPRNGs such as /dev/urandom use the same cryptographic primitives that symmetric ciphers (such as AES, Twofish, Salsa20, ChaCha20, etc.) use. In the unlikely event that our CSPRNGs are broken (meaning /dev/urandom outputs "unsafe bits"), our symmetric ciphers will all be broken too. Therefore there is absolutely no point in insisting on using /dev/random to generate keys that will be used with symmetric ciphers.
(That's a little hand-wavy but I hope you get the general idea.)
Disclaimer: I am not a cryptographer.
What threw me off was that part: "Still, if you insist on never handing out random numbers that are not “backed” by sufficient entropy, you might be nervous here. I'm sleeping sound because I don't care about the entropy estimate."
I was missing the fact that the CSPRNG only needs to be seeded once to be safe, and reseeding is only a "nice thing" that's not really needed. To be fair, the article cover this, I guess I just didn't understand that part really well.
I've got it now, and it actually make sense. Thanks to you, and everyone else that used some time to educate me.
It's frustrating the the Linux random man page implies otherwise, because the idea is cryptographically nonsensical.
In other words, if the seed hasn't leaked it is easier to brute-force the key than to fit the CPRNG output that generated it.
>If you are unsure about whether you should use /dev/random or /dev/urandom, then probably you want to use the latter. As a general rule, /dev/urandom should be used for everything except long-lived GPG/SSL/SSH keys
Later:
>While some safety margin above that minimum is reasonable, as a guard against flaws in the CPRNG algorithm, no cryptographic primitive available today can hope to promise more than 256 bits of security, so if any program reads more than 256 bits (32 bytes) from the kernel random pool per invocation, or per reasonable reseed interval (not less than one minute), that should be taken as a sign that its cryptography is not skilfully implemented.
What exactly is the problem with blocking IO if you can't read faster than 32 bytes/min (or slower)?
/edit:
In your link:
>About 256 bits of entropy are enough to get computationally secure numbers for a long, long time.
I'm not a cryptology expert and therefor delegate that stuff to qualified people. But this sounds like utter bullshit. If your OpenSSL needs n bits of entropy, it does need it, and feeding it with more pseudo random numbers from that pools seems like a horrible idea. This post convinces me that /dev/random is the right thing, and not /dev/urandom, since blocking seems to be a very, very important feature. While I wouldn't trust me to get random generators right, i'd trust that blog a way less.
http://sockpuppet.org/blog/2014/02/25/safely-generate-random...
That means if you can't trust to these generators then you can't trust your encryption (i.e. you are screwed anyway).
Why is no one authoritative on cryptography setting these defaults so that determining "what programs do with OpenSSL" is so random. Why is OpenSSL leaving these choices to programmers by default?
It seems like a terrible, terrible thing that people are micro-optimizing how big their seed is, what their source is, etc. This can not be good for security.
https://www.schneier.com/blog/archives/2008/05/random_number...
Edit: oh right, it led to the SSH blacklist. Sorry.
This assumes OpenSSL's CSPRNG is solid, and that /dev/urandom is returning 32 bytes of data that can't be guessed in less than brute force time. I'd be curious to know how big the internal state of that CSPRNG is, actually.