Java 中的 HMAC-SHA256 产生与 JavaScript 不同的输出

HMAC-SHA256 in Java produces different output than JavaScript

我一直在尝试将一些 NodeJS 代码移植到 Java,以便向 API 发出 HMAC 签名请求。我已经能够将代码简化到一定程度,编码显然会影响输出。

这是我在 Java脚本中的代码:

var APIKey = "secret";
var secretByteArray = CryptoJS.enc.Base64.parse(APIKey);
var hash = CryptoJS.HmacSHA256("Message", secretByteArray);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
//alert(hashInBase64);
document.write(hashInBase64);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac-sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>

这是 Java 代码:

try {
        String secret = "secret";
        String message = "Message";

        byte[] secretByteArray = Base64.getEncoder().encode(secret.getBytes());

        //byte[] secretByteArray = Base64.encodeBase64(secret.getBytes("utf-8"), true);

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(secretByteArray, "HmacSHA256");
        sha256_HMAC.init(secret_key);

        String hash = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(message.getBytes()));
        System.out.println(hash);
    }
    catch (Exception e){
        System.out.println("Error");
    }

如果我不对 "secret" 进行 base64 编码,我会得到相同的输出,但我希望使用编码字符串得到相同的结果。我怀疑编码的字节数组有填充或符号差异。

您的 Java 代码使用 Base64.getEncoder().encode 转换为 Base64。

您的 Java脚本代码使用 CryptoJS.enc.Base64.parse Base64 转换。

你需要使它们匹配。