首页 > 解决方案 > 在 javascript 中计算 SHA1 哈希,UTF-16 字符串的问题

问题描述

我正在编写一个使用 AES-128 的 javascript 客户端来与用 java 编写的服务器进行通信。服务器使用 SHA1 散列从字符串生成密码。然后为服务器加密数据。这适用于 ASCII 字符,但对于 javascript 中更高的 unicode 字符则失败,因为 js 字符串采用 UTF-16 格式,因此对字符串的字节进行哈希处理会产生不同的结果。我正在使用的测试套件有一个包含 £ 的密码。这是 UTF-16 中的 0x00a3 和 UTF-8 中的 0xC2 0xA3。我不知道如何将 UTF-16 unicode 代码点转换为 UTF-8 的 uint8array。我尝试使用 TextEncoder/TextDecoder 失败。

下面的代码显示了这个问题。使用 java、C# 和 perl,预期的 base64 编码散列,对于 AES-128 密钥被截断为 16 个字节,结果为 +guOwqu6/gVmQzArLrzGQg==。运行下面的 javascript 会给我 1nNTS1vHThwvV7lUI0EB9g==。

const crypto = require('crypto');

function getSecretKey(key) {
    var hasher = crypto.createHash('sha1');
    const data = hasher.update(Buffer.from(key, 'utf16le'));
    return data.digest().slice(0, 16).toString('base64');
}

console.log(getSecretKey("abcd£"));

这是一个几乎可以做同样事情的 perl 程序。它不会截断为 16 个字节,但输出应该匹配到最后几个字符。

use Digest::SHA1  qw(sha1 sha1_hex sha1_base64);
$digest = sha1_base64("abcd£");
print $digest;
print "\n";

必须有一种方法可以从 UTF-16 代码点的 javascript 字符串创建 UTF-8 字符的 Buffer 或 uint8Buffer。

标签: javascriptutf-8sha1utf-16

解决方案


推荐阅读