【问题标题】:Can the key be empty while generating HmacSHA256 using java使用java生成HmacSHA256时密钥可以为空吗
【发布时间】:2023-05-04 00:05:02
【问题描述】:

我正在用 Java 生成 HMAC-SHA256。如果 key 设置为 "" 则抛出以下异常:

java.lang.IllegalArgumentException: Empty key 

但我可以使用 JavaScript 中的空键生成 HMAC CryptoJS.HmacSHA256("Sample Text", "") CryptoJS 中的方法。在 Java 中,空格也被接受为键,但不接受空键。

Java中可以使用空键吗?

【问题讨论】:

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

标签: java cryptography sha256 hmac cryptojs


【解决方案1】:

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 的库,例如 Bouncy Castle,完全避开 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 对象,那么这不是适合您的解决方案。


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

【讨论】: