SubtleCrypto调用importKey导入导出公钥返回undefined如何解决
问题原因
- 你的
importPublicKey函数没有返回window.crypto.subtle.importKey产生的Promise对象,函数执行完没有显式返回值,自然得到undefined。SubtleCrypto的所有方法都是异步的,返回Promise,你必须把这个Promise返回给调用方,才能拿到最终的密钥结果。 - 你调用
importPublicKey时直接同步赋值let resultingKey = importPublicKey(pem),没有等待异步操作完成,哪怕函数返回了Promise,直接拿到的也只是Promise对象而非最终密钥,必须用await或者.then()回调获取结果。
修复方案
首先修改importPublicKey函数,在window.crypto.subtle.importKey前加return:
function importPublicKey(pem) { const pemHeader = "-----BEGIN PUBLIC KEY-----"; const pemFooter = "-----END PUBLIC KEY-----"; let pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length) pemContents = pemContents.replace(/\s/g, ''); console.log('pemContents:', pemContents) let binaryDerString = window.atob(pemContents); const binaryDer = str2ab(binaryDerString); console.log('binaryDer', binaryDer) // 新增return返回Promise return window.crypto.subtle.importKey( "spki", binaryDer, { name: "RSA-OAEP", hash: { name: "SHA-256" } }, true, ["encrypt"] ).catch(function(err) { console.log('err: ', err); }) }
然后修改调用逻辑,使用await等待异步操作完成(需要给外层函数加async标识):
window.crypto.subtle.exportKey( "spki", keyPair.publicKey ).then(async function(exportedPublicKey) { // 给回调函数加async var pem = toPemP(exportedPublicKey); console.log(pem); let resultingKey = await importPublicKey(pem) // 加await等待Promise执行完成 console.log('keyPairPublic: ', keyPair.publicKey) console.log('resultingKey: ', resultingKey) }).catch(function(err) { console.log(err); });
关于ArrayBuffer大小不一致的问题:你导出时的exportedPublicKey和导入前的binaryDer内容完全一致,大小不同是日志打印的差异,和当前问题无关,修改后不会影响导入结果。
内容的提问来源于stack exchange,提问作者Tomatotum
相关产品推荐
相关产品推荐

