代码之家  ›  专栏  ›  技术社区  ›  Oleksandr

如何在javascript中使base64 hmacsha256字节有效负载签名等价于java?

  •  0
  • Oleksandr  · 技术社区  · 6 年前

    在java中对我们使用的一些数据进行签名 Mac 允许对任何字节数组进行签名的实例。如何在javascript中创建一个为同一字节数组生成相同签名的函数?

    Java实现(方法)的一个例子 sign 标志 message 具有 HmacSHA256 比皈依者 signature 进入URL安全base64字符串):

    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
    
        byte[] secret = new byte[5];
        secret[0] = 0x1e;
        secret[1] = 0x03;
        secret[2] = 0x01;
        secret[3] = 0x02;
        secret[4] = 0x03;
    
        byte[] message = new byte[5];
        message[0] = 0x01;
        message[1] = 0x03;
        message[2] = 0x02;
        message[3] = 0x1e;
        message[4] = 0x03;
    
        System.out.println(sign(secret, message));
    }
    
    private static String sign(byte[] secret, byte[] message) throws NoSuchAlgorithmException, InvalidKeyException {
    
        Mac sha256Hmac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(secret, "HmacSHA256");
        sha256Hmac.init(secretKey);
    
        byte[] signature = sha256Hmac.doFinal(message);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(signature);
    }
    

    上面的例子产生了 q-l6FioFNkAqMIIxX5rs3AF-VnGIzpApCSSDHmnmjF8 签名字符串。我试图创造出 签名 方法获取相同的签名。

    function main(){
        var secret = [5];
        secret[0] = 0x1e;
        secret[1] = 0x03;
        secret[2] = 0x01;
        secret[3] = 0x02;
        secret[4] = 0x03;
    
        var message = [5];
        message[0] = 0x01;
        message[1] = 0x03;
        message[2] = 0x02;
        message[3] = 0x1e;
        message[4] = 0x03;
    
        console.log(sign(secret, message));
    }
    
    function sign(secret, message){
    
        // ?
    
    }
    

    我找不到方法用 CryptoJS 是的。

    1 回复  |  直到 6 年前
        1
  •  0
  •   SimoMatavulj    6 年前

    安装后,CryptoJS中应包含Base64和HMACSHA256。尝试以下方法:

    function sign(secret, message){
    const hash = CryptoJS.HmacSHA256(message.join(''), secret.join('')); 
    const hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
    return hashInBase64}
    
        2
  •  0
  •   Oleksandr    6 年前

    解决办法似乎并不复杂。使用前 CryptoJS 我们必须正确地将字节数组转换为字符串。回来后 base64 字符串我们应该将其转义为url友好字符串。

    function sign(secret, message){
    
        var secretString = String.fromCharCode.apply(String, secret);
        var messageString = String.fromCharCode.apply(String, message);
    
        var hash = CryptoJS.HmacSHA256(messageString, secretString);
        return CryptoJS.enc.Base64.stringify(hash).replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
    }