javascript - 在 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。
解决方案
推荐阅读
- c# - Visual Studio 中的变量命名约定是否有任何规则,可以在开发时强制执行?
- collections - JasperStudio:向多选输入控件添加字符串 (java.util.Collection)
- java - ExecutorService 在休息 API 中使用
- html - Bootstrap V3:网格系统无法将两个 div 放在一行中
- r - 计算两个 posixCT 日期之间因子变量的出现次数
- javascript - 从列出/关联经过身份验证的用户的 MongoDB 文档中获取对象
- java - 如何将普通pdf转换为小册子pdf,反之亦然
- sqlite - 使用 SchemaSpy 为本地 sqlite 数据库生成架构时出现连接失败警告
- c# - 在 C# 中对列表中的每个输入执行计算
- javascript - 数组返回长度为 0,尽管它有值