使用java生成HmacSHA256时,密钥是否可以为空

使用java生成HmacSHA256时,密钥是否可以为空,java,cryptography,sha256,hmac,cryptojs,Java,Cryptography,Sha256,Hmac,Cryptojs,我正在用Java生成HMAC-SHA256。如果键设置为,则引发以下异常: java.lang.IllegalArgumentException: Empty key 但是我可以使用 CryptoJS.hmacsha256示例文本,CryptoJS中的方法。在Java中,也接受空格作为键,但不接受空键 可以在Java中使用空键吗?Java—就像大多数编程语言一样—是图灵完成的,所以您可以执行其他语言可以执行的任何计算,即使您必须自己编程 不幸的是,您显示的异常是SecretKeySpec的一

我正在用Java生成HMAC-SHA256。如果键设置为,则引发以下异常:

java.lang.IllegalArgumentException: Empty key 
但是我可以使用 CryptoJS.hmacsha256示例文本,CryptoJS中的方法。在Java中,也接受空格作为键,但不接受空键


可以在Java中使用空键吗?

Java—就像大多数编程语言一样—是图灵完成的,所以您可以执行其他语言可以执行的任何计算,即使您必须自己编程

不幸的是,您显示的异常是SecretKeySpec的一部分,这意味着您无法直接生成密钥。您也不能只使用不同的提供程序,因为密钥创建是相同的

但是,如果您很聪明,那么您将看到SecretKey只是一个接口,这意味着您可以实现它:

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];
    }
}
现在很明显,Java的HMAC实现本身并不禁止空键,因此这将起作用。当然,它可能在不同的Java实现或版本中不起作用,尽管在HMAC中插入检查似乎不太可能,因为它可能是HMAC的有效用例

或者,您当然可以使用另一个实现HMAC的库,例如BouncyCastle,并完全避开JCA

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);
当然,如果您的代码需要Java Mac对象,那么这不是您的解决方案


此答案中两个选项中的代码产生相同的结果,因此您可以非常确定它是否有效。

HMAC键被描述为字节,而不是字符串,因此将键指定为或空格根本没有意义。Vivek,请始终在您的问题中显示代码和完整堆栈跟踪。