I am generating HMAC-SHA256 in Java. If the key is set to "" then The following exception is thrown:
java.lang.IllegalArgumentException: Empty key
But I can generate the HMAC using empty key in JavaScript using the
CryptoJS.HmacSHA256("Sample Text", "")
method in CryptoJS. In Java a space is also accepted as key but empty key is not accepted.
Is it possible to use empty key in Java?
Java - as most programming languages - is Turing complete, so you can do any calculation that another language can do, even if you have to program it yourself.
Unfortunately the exception you've shown is part of SecretKeySpec
, which means that you cannot generate the key directly. You cannot just use a different provider either because the key creation would be the same.
However, if you're smart then you'll see that SecretKey
is just an interface, which means you can implement it:
public static class EmptyKey implements SecretKey {
private static final long serialVersionUID = 1L;
@Override
public String getAlgorithm() {
return "HMAC";
}
@Override
public String getFormat() {
return "RAW";
}
@Override
public byte[] getEncoded() {
// return empty key data
return new byte[0];
}
}
now apparently the HMAC implementation of Java doesn't disallow empty keys itself, so this will work. Of course it might not work in different implementations or versions of Java, although inserting a check in HMAC doesn't seem likely as it could be a valid use case of HMAC.
Alternatively you can of course use another library that implements HMAC, such as Bouncy Castle, and sidestep the JCA altogether.
HMac hmac = new HMac(new SHA256Digest());
hmac.init(new KeyParameter(new byte[0]));
byte[] out = new byte[hmac.getMacSize()];
// you need to insert the message here, I'm using an empty message
hmac.doFinal(out, 0);
Of course, if your code requires a Java Mac
object then this is not the solution for you.
The code in both options in this answer produce the same results, so you can be pretty sure that it is valid.