Search code examples
javacryptographysha256hmaccryptojs

Can the key be empty while generating HmacSHA256 using java


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?


Solution

  • 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.