首页 > 解决方案 > 这里究竟做了什么?尝试将代码从 Java 传输到 NodeJS

问题描述

我目前正在尝试将一些编码脚本从 Java 转移到 NodeJs。

目前的Java脚本如下:

public static final char[] chars = "0123456789abcdef".toCharArray();

public static String sha1Digest(String str) {
    try {
        MessageDigest instance = MessageDigest.getInstance('SHA-1');
        instance.reset();
        instance.update(str.getBytes('UTF-8'));
        return lastEncode(instance.digest());
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}


public static String lastEncode(byte[] bArr) {
    StringBuilder encoded = new StringBuilder(bArr.length * 2);
    for (byte b : bArr) {
        encoded.append(chars[(b >> 4) & 15]);
        encoded.append(chars[b & 15]);
    }
    return encoded.toString();
}

传递给 sha1Digest 函数的初始参数是一个字符串,该字符串由一个附加了密钥的 URL 组成。

目前,我正在尝试将代码转移到我拥有此代码的 NodeJs(现在):

async function sha1Digest(str) {
  try {
    const sha1 = crypto.createHmac("SHA1");
    const hmac = sha1.update(new Buffer(str, 'utf-8'));
    return encoder(hmac.digest());
  } catch (e) {
    console.dir(e);
  }
}

async function lastEncode(bArr) {
    let chars = "0123456789abcdef".split('')
    let sb = '';
    for (b in bArr) {
        sb = sb + (chars[(b >> 4) & 15]);
        sb = sb + (chars[b & 15]);
    }
    return sb;
}

可悲的是,我不了解 lastEncode 中 for 循环中的部分的作用。有没有人能帮我解决这个问题,并验证 sha1Digest 函数在 NodeJS 中是否正确?

非常感激!

标签: javanode.jscryptography

解决方案


lastEncode将字节数组转换为十六进制半字节。它将 array:new byte[] {10, 16, (byte) 255}转换为 string "0a10ff"。(0a 是 10 的十六进制表示法,ff 是 255 的十六进制表示法,等等 - 如果这对你来说听起来像是 gobbledygook,那么网络上有很多关于十六进制的教程:P)。

你的 javascript 翻译搞砸了,因为你正在加入,. 更一般地说,要执行之前的“字节到半字节”操作,请参阅这个 SO answer

只需自行测试 lastEncode 函数。在 java 中运行它,然后运行你的 javascript 端口,并确保在两个变体中生成完全相同的字符串。只有这样,才能进入散列部分。

注意:需要明确的是,这个协议相当愚蠢——你可以自己散列字节数组,没有必要浪费大量时间把它变成十六进制半字节(它总是正好是输入的 2 倍)然后散列。但是,据推测,此时您不能乱用协议。但如果可以,请改变它。它会更快,解释更简单,代码更少。双赢。

编辑:注意:您还在 javascript 端使用不同的哈希算法(HMAC-SHA1 与 SHA1 不同)。


推荐阅读