如何使用 Web Crypto API 创建哈希?
How to create a hash using Web Crypto API?
我正在尝试在客户端创建 SHA-1 哈希。我正在尝试使用 Web Crypto API 来执行此操作,但是当我将输出与各种在线工具提供的内容进行比较时,结果完全不同。我认为问题出在 ArrayBuffer 到 Hex 的转换中。这是我的代码:
function generateHash() {
var value = "mypassword";
var crypto = window.crypto;
var buffer = new ArrayBuffer(value);
var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}
document.write
的输出应该是:
91dfd9ddb4198affc5c194cd8ce6d338fde470e2
但不是,我得到了一个完全不同的不同长度的散列(应该是 40)。我可以就这个问题提出一些建议吗?谢谢
问题似乎更多是从字符串到 ArrayBuffer
的输入转换。例如。使用 str2ab()
代码有效:
generateHash();
function generateHash() {
var value = "mypassword";
var crypto = window.crypto;
var buffer = str2ab(value); // Fix
var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}
//
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
预期输出:
91dfd9ddb4198affc5c194cd8ce6d338fde470e2
使用调试器,看起来 var buffer = new ArrayBuffer(value);
导致 buffer
成为一个空的 ArrayBuffer。 value
中存储的文本字符串必须采用 utf-8 编码才能正确转换为字节,然后可以将其作为输入传递给 crypto.subtle.digest()
函数。
尝试更改:
var buffer = new ArrayBuffer(value);
至:
var buffer = new TextEncoder("utf-8").encode(value);
这将创建一个 Uint8Array(如 crypto.subtle.digest()
所预期的那样),其中包含对 'value' 中的文本字符串进行 utf-8 编码的字节。这应该可以解决问题并产生您期望的结果。
我正在尝试在客户端创建 SHA-1 哈希。我正在尝试使用 Web Crypto API 来执行此操作,但是当我将输出与各种在线工具提供的内容进行比较时,结果完全不同。我认为问题出在 ArrayBuffer 到 Hex 的转换中。这是我的代码:
function generateHash() {
var value = "mypassword";
var crypto = window.crypto;
var buffer = new ArrayBuffer(value);
var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}
document.write
的输出应该是:
91dfd9ddb4198affc5c194cd8ce6d338fde470e2
但不是,我得到了一个完全不同的不同长度的散列(应该是 40)。我可以就这个问题提出一些建议吗?谢谢
问题似乎更多是从字符串到 ArrayBuffer
的输入转换。例如。使用 str2ab()
代码有效:
generateHash();
function generateHash() {
var value = "mypassword";
var crypto = window.crypto;
var buffer = str2ab(value); // Fix
var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}
//
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
预期输出:
91dfd9ddb4198affc5c194cd8ce6d338fde470e2
使用调试器,看起来 var buffer = new ArrayBuffer(value);
导致 buffer
成为一个空的 ArrayBuffer。 value
中存储的文本字符串必须采用 utf-8 编码才能正确转换为字节,然后可以将其作为输入传递给 crypto.subtle.digest()
函数。
尝试更改:
var buffer = new ArrayBuffer(value);
至:
var buffer = new TextEncoder("utf-8").encode(value);
这将创建一个 Uint8Array(如 crypto.subtle.digest()
所预期的那样),其中包含对 'value' 中的文本字符串进行 utf-8 编码的字节。这应该可以解决问题并产生您期望的结果。