使用JS SubtleCrypto实现RSA加解密时atob编码报错如何解决
问题原因
- 加密函数无返回值:
importPublicKeyAndEncrypt仅在控制台打印加密结果,没有返回生成的Base64加密字符串,你赋值的变量a实际是该异步函数返回的空Promise对象,将Promise传入atob方法自然触发编码错误。 - PEM密钥未过滤空白字符:你定义的公钥、私钥模板字符串包含开头换行、内容缩进空格,
getSpkiDer、getPkcs8DerDecode方法直接截取头尾标识后就传入atob解码,空白字符会导致Base64解码失败。 - 异步调用未加await:
importPublicKeyAndEncrypt是异步函数,直接调用拿到的是pending状态的Promise,必须加await等待执行完成才能拿到加密结果。
修复代码
1. 修改加密函数,新增返回值
async function importPublicKeyAndEncrypt(str) { try { const pub = await importPublicKey(publicKey); console.log(pub); const encrypted = await encryptRSA(pub, new TextEncoder().encode(str)); const encryptedBase64 = window.btoa(ab2str(encrypted)); console.log(encryptedBase64.replace(/(.{64})/g, '$1\n')); // 新增返回加密后的Base64串 return encryptedBase64; } catch (error) { console.log(error); throw error; } }
2. 修改密钥解析方法,过滤空白字符
修改getSpkiDer和getPkcs8DerDecode中的pemContents处理逻辑,去掉所有空格、换行、缩进:
function getSpkiDer(spkiPem) { const pemHeader = '-----BEGIN PUBLIC KEY-----'; const pemFooter = '-----END PUBLIC KEY-----'; var pemContents = spkiPem.substring( pemHeader.length, spkiPem.length - pemFooter.length ); // 新增:过滤所有空白字符 pemContents = pemContents.replace(/\s/g, ''); var binaryDerString = window.atob(pemContents); return str2ab(binaryDerString); } function getPkcs8DerDecode(pkcs8Pem) { const pemHeader = '-----BEGIN PRIVATE KEY-----'; const pemFooter = '-----END PRIVATE KEY-----'; var pemContents = pkcs8Pem.substring( pemHeader.length, pkcs8Pem.length - pemFooter.length ); // 新增:过滤所有空白字符 pemContents = pemContents.replace(/\s/g, ''); var binaryDerString = window.atob(pemContents); return str2ab(binaryDerString); }
正确调用示例
必须在异步作用域内加await调用:
(async () => { // 等待加密完成拿到加密串 const encryptedStr = await importPublicKeyAndEncrypt('hello'); // 传入加密串解密 await importPrivateKeyAndDecrypt(encryptedStr); })();
内容的提问来源于stack exchange,提问作者Red
相关产品推荐
相关产品推荐

