TypeScript中window.crypto.subtle导入密钥与签名报错问题排查
问题原因及修复方案
核心问题1:异步Promise未正确处理
importPrivateKey方法返回的是Promise<CryptoKey>,你直接把Promise对象传给crypto.subtle.sign,但该方法需要的是实际的CryptoKey实例,这就是TypeScript报错的直接原因。
修复方式:用async/await处理异步
修改createSignature2为异步函数,通过await获取实际的私钥:
async createSignature2(){ // 用await等待Promise解析,拿到实际的CryptoKey let privateKey = await this.importPrivateKey(); console.log(privateKey) let data = this.str2ab("Test buffer") let sign = window.crypto.subtle.sign( { name: "ECDSA", hash: {name: "SHA-512"}, }, privateKey, data ) .then(function(signature){ console.log(new Uint8Array(signature)); }) .catch(function(err){ console.error(err); }); }
核心问题2:密钥导入的算法参数不匹配
你要做ECDSA签名,但导入私钥时指定的算法是RSA-PSS,这会导致导入的密钥和签名算法不兼容,即使解决了Promise问题,后续也会运行报错。
修复方式:修改导入密钥的算法配置
把importPrivateKey里的算法参数改为ECDSA对应的配置:
const pem = "-----BEGIN PRIVATE KEY-----\nByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgUIcMiv/YpEgR1CKRsL6sS85BVo6lYft/S5nIjTlCHvihRANCAATykP7bc8\n-----END PRIVATE KEY-----" // fetch the part of the PEM string between header and footer const pemHeader = "-----BEGIN PRIVATE KEY-----"; const pemFooter = "-----END PRIVATE KEY-----"; const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length); // base64 decode the string to get the binary data const binaryDerString = window.atob(pemContents); // convert from a binary string to an ArrayBuffer const binaryDer = this.str2ab(binaryDerString); return window.crypto.subtle.importKey( "pkcs8", binaryDer, { name: "ECDSA", // 替换为ECDSA,和签名算法一致 namedCurve: "P-256", // 根据你的私钥实际曲线填写,比如P-256/P-384/P-521 hash: "SHA-512", }, true, ["sign"] );
注意:namedCurve需要和你的私钥生成时使用的椭圆曲线一致,比如常见的P-256、P-384等,根据实际情况调整。
内容的提问来源于stack exchange,提问作者Maniac_1979
相关产品推荐
相关产品推荐

