我想使用内置的浏览器加密对象,而不是在浏览器项目中导入加密库。
我不想需要这个。
npm i crypto
以下代码说明了尝试使用这两个库对简单消息进行签名,但是在使用内置加密对象时我得到了不同的结果。输出被记录到控制台。
// START CRYPTO LIBRARY METHOD
import crypto from 'crypto';
const HMAC_SHA256_KEY = {
API_KEY: '***',
SECRET_KEY: '***'
};
const queryString = `timestamp=${(new Date().getTime())}`;
const signature = crypto
.createHmac('sha256', HMAC_SHA256_KEY.SECRET_KEY)
.update(queryString)
.digest('hex')
console.log("standard encrypt", signature);
// START NATIVE LIBRARY METHOD
const getUtf8Bytes = (str: string) => {
return new Uint8Array(
[...(unescape(encodeURIComponent(str)))].map(c => c.charCodeAt(0))
);
};
// @ts-ignore
const builtInCrypto = window.crypto || window.msCrypto;
builtInCrypto.subtle.importKey(
'raw',
getUtf8Bytes(HMAC_SHA256_KEY.SECRET_KEY),
{
name: 'HMAC', hash: 'SHA-256'
},
true, ['sign']
).then(key => {
builtInCrypto.subtle.sign(
'HMAC',
key,
getUtf8Bytes(queryString))
.then(signature => {
console.log('builtIn Signature', btoa(String.fromCharCode(...(new Uint8Array(signature)))));
})
})
显然我做错了什么,但是什么?为什么我会得到不同的 native 加密输出?
最佳答案
对于 HMAC_SHA256_KEY.SECRET_KEY
和 queryString
的相同值(最后一个参数取决于时间,因此每次运行都有不同的值) )两个脚本都返回相同 HMac,但采用不同编码,从而导致不同的输出。在 NodeJS/crypto 代码中,HMac 采用十六进制编码,在 JavaScript/Web Crypto API 代码中采用 Base64 编码。
为了确保输出相同,两个脚本中必须使用相同的编码。 JavaScript/Web Crypto API 代码中的 HMac 也必须是十六进制编码,请参见例如here对于合适的方法,或者 NodeJS/crypto 代码中的 HMac 必须采用 Base64 编码(通过传递 'base64'
而不是 'hex'
作为digest
的参数)。
关于javascript - 如何让 window.crypto.subtle 输出与 'crypto' js 库相同的签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62988947/