-2

Following line generate a sha512 secret via jdk's KeyGenerator.

SecretKey secretKey = KeyGenerator.getInstance("HmacSHA512").generateKey();

I am wondering is the key random secure?

Or, should I init the generator with a SecureRandom instance explicitly, before generate the key?

Eric
  • 22,183
  • 20
  • 145
  • 196
  • 2
    Read the javadoc: it answers your question: *All key generators share the concepts of a keysize and a source of randomness. There is an init method in this KeyGenerator class that takes these two universally shared types of arguments. There is also one that takes just a keysize argument, and uses the SecureRandom implementation of the highest-priority installed provider as the source of randomness (or a system-provided source of randomness if none of the installed providers supply a SecureRandom implementation), and one that takes just a source of randomness.*. – JB Nizet Feb 23 '18 at 18:19
  • @JBNizet So, for `HmacSHA512` can you tell the simple version of answer to the question? – Eric Feb 23 '18 at 18:26
  • 2
    Again, read. Carefully. **There is also one that takes just a keysize argument, and uses the SecureRandom implementation of the highest-priority installed provider as the source of randomness**. What is unclear? If you don't initialize with a SecureRandom, it *uses the SecureRandom implementation of the highest-priority installed provider as the source of randomness*. Doesn't that answre your question? How doesn't it? – JB Nizet Feb 23 '18 at 18:27
  • @JBNizet The result key is 512 bits, since it's SHA512, what's the keysize argument for in this case ... – Eric Feb 23 '18 at 18:30
  • The javadoc says: *Throws: InvalidParameterException - if the keysize is wrong or not supported.*. – JB Nizet Feb 23 '18 at 18:33
  • @JBNizet Thus, in this case should not call any method with a keysize included in the param list at all ... so without calling the init method, it goes back to my original question, what's the default behavior, without calling the init method. – Eric Feb 23 '18 at 18:38
  • If your question isn't actually answered by the documentation, then clarify your question. – Mark Rotteveel Feb 23 '18 at 18:55
  • @MarkRotteveel The question is really clear I think, it's just `Is it still random secure, without calling init() method`. This part of source code is not available in the oracle jdk, even in the open jdk, only interface & abstract class have the source code, but didn't found the code of specific algorithm impl, I asked the question after reading the documents & source code from both oracle jdk & open jdk, as well as many articles from Google, but didn't found anywhere clarify the behavior of `HmsSHA512`. – Eric Feb 23 '18 at 19:00
  • The javadoc says, several times, that if you don't provide a SecureRandom, then it uses **the SecureRandom implementation of the highest-priority installed provider**. What more do you need? – JB Nizet Feb 23 '18 at 19:13
  • @JBNizet That javadoc belongs to `init(int keysize)` method, the question is about when no `init` is called, which means the javadoc don't necessarily apply to this case when no `init` is called, in which case, it should be implementation specific, in my test, I didn't call any `init()`, the keys are generated successfully, I am just not sure is it random secure. – Eric Feb 23 '18 at 19:17
  • 2
    From the javadocs: *In case the client does not explicitly initialize the KeyGenerator (via a call to an init method), each provider must supply (and document) a default initialization.* So it becomes provider-specific, and guess what? The [Oracle providers](https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html) don't really document this aspect. Since I am not a fan of defaults anyway I'd recommend you always call an `init()` method. – President James K. Polk Feb 23 '18 at 19:52
  • @JamesKPolk Yeah, I agree that. – Eric Feb 23 '18 at 20:11

1 Answers1

1

Just for completeness you could call the init method using a key size of 512 bits. However, the default key size of HMAC is the same size as the output. So in that sense it is very reasonable to assume that this key size is set by default. Indeed, calling the init method using a constant value should be avoided.

As for the implementation, it is as likely that if you don't call the init method explicitly that a default value is assumed and that a SecureRandom instance is chosen. However, you are correct in the sense that this is a logical provider default; it should have been specified as a requirement to all providers.

Some idea from what is going on here is in KeyGeneratorCore. All of the provider code is online, so not finding it is up to not looking deeply enough, although admittedly you need some Google foo to find it.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • I did a debug in the jdk source code, if no `init()` is called, then random is null at first, then in `KeyGeneratorCore`'s `implGenerateKey()` method it will call `SunJCE.getRandom()` to init the random, and that will get a `static final` random belongs to `SunJCE$SecureRandomHolder` class. So, it does has a random, and the random is shared among the jvm as a default random. With tips in the answer I also found `HmacCore` and `HmacCore$HmacSHA512`, which are the implementation for `HmacSHA512` algorithm. – Eric Feb 25 '18 at 02:09
  • I just have one concern, is it a good practice to use a jvm-wide shared `SecureRandom` instance, or it's better to specify a new instance by developers each time generate a key? I have check this post where the answers have different opinions: https://stackoverflow.com/questions/295628/ – Eric Feb 25 '18 at 02:11
  • 1
    Random generators are hard to understand subjects. Fortunately a well seeded CSPRNG isn't likely to be all that vulnerable. So as long as you use one and don't provide the initial seed yourself, it should be rather secure (on desktops and servers anyway, embedded CPU's are a bit more tricky). Personally I would either stay with the default and not provide a specific RNG, use `SecureRandom.getInstanceStrong()` for long term keys or use an BSI AIS 31 or FIPS validated hardware device (this last one may not be available to you :P ). – Maarten Bodewes Feb 25 '18 at 11:45
  • 1
    I've put in a lot of comments below the answers of that question; they are not all that great and the accepted answer contains wrong information. – Maarten Bodewes Feb 25 '18 at 12:18