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

Raú*_*Roa 3 java sha256 hmac

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

这是我的 JavaScript 代码:

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);
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

这是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");
    }
Run Code Online (Sandbox Code Playgroud)

如果我不将“秘密”编码为 base64,我会得到相同的输出,但我希望使用编码字符串获得相同的结果。我怀疑编码的字节数组有填充或符号差异。

SLa*_*aks 7

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

您的 JavaScript 代码用于Base64CryptoJS.enc.Base64.parse转换。

你需要让这些匹配。