sessionstorage 不能直接存储 rsa 公钥对象,必须先导出为字符串格式(推荐 jwk)再存入;jwk 可直接 json.stringify 存储,读取后用 importkey 重新导入,安全且兼容性好。

SessionStorage 不能直接存储 RSA 公钥对象(比如 RSAKey 实例或 Web Crypto API 的 CryptoKey),它只支持字符串。所以“存储动态生成的临时 RSA 公钥”的核心是:**先将公钥导出为标准字符串格式(如 PEM 或 JWK),再存入 SessionStorage**。
公钥必须导出为字符串才能存入 SessionStorage
浏览器的 sessionStorage 是纯字符串键值对存储,任何非字符串数据(包括 CryptoKey、ArrayBuffer、对象等)都会被自动调用 .toString(),导致信息丢失。因此必须显式导出:
- 使用 Web Crypto API 生成密钥对后,调用
window.crypto.subtle.exportKey('spki', publicKey)得到 DER 格式 ArrayBuffer - 再将 ArrayBuffer 转为 Base64 字符串,拼装成 PEM 格式(即以
-----BEGIN PUBLIC KEY-----开头) - 或导出为 JSON Web Key(JWK)格式(
'jwk'),它本身就是 JSON 对象,可直接JSON.stringify()存储
推荐做法:用 JWK 格式 + JSON.stringify 存储
JWK 更轻量、可读、易解析,且兼容性好(Chrome 86+、Firefox 87+、Edge 86+ 支持)。示例代码:
// 1. 生成 RSA 密钥对(临时,仅会话内使用)
const keyPair = await window.crypto.subtle.generateKey(
{ name: 'RSA-OAEP', modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256' },
true,
['encrypt', 'decrypt']
);
// 2. 导出公钥为 JWK 格式(返回 Promise<jsonwebkey>)
const jwk = await window.crypto.subtle.exportKey('jwk', keyPair.publicKey);
// 3. 存入 sessionStorage(自动序列化为字符串)
sessionStorage.setItem('tempRsaPubKey', JSON.stringify(jwk));
// ✅ 后续可随时读取并重新导入:
const jwkStr = sessionStorage.getItem('tempRsaPubKey');
if (jwkStr) {
const parsedJwk = JSON.parse(jwkStr);
const importedKey = await window.crypto.subtle.importKey('jwk', parsedJwk, { name: 'RSA-OAEP', hash: 'SHA-256' }, false, ['encrypt']);
}
</jsonwebkey>
注意事项与安全提醒
- SessionStorage 数据在标签页关闭后自动清除,适合单次会话的临时公钥,但不适用于跨标签页共享(此时考虑 IndexedDB 或内存变量 + postMessage)
- 不要存私钥 ——
exportKey私钥需extractable: true,且私钥绝不可写入任何前端存储(包括 SessionStorage) - PEM 方式需手动 Base64 编码/解码和换行处理,容易出错;JWK 更稳妥
- 若后端需要 PEM 格式公钥,可在前端导出 SPKI 后转 Base64 并加 PEM 头尾,但存储仍建议用 JWK,需要时再转换
如果必须用 PEM 格式存储
可封装一个工具函数避免手拼错误:
function spkiToPem(spkiBuffer) {
const base64 = btoa(String.fromCharCode(...new Uint8Array(spkiBuffer)));
const lines = base64.match(/.{1,64}/g) || [];
return `-----BEGIN PUBLIC KEY-----\n${lines.join('\n')}\n-----END PUBLIC KEY-----`;
}
// 使用:
const spki = await window.crypto.subtle.exportKey('spki', keyPair.publicKey);
sessionStorage.setItem('rsaPubKeyPem', spkiToPem(spki));
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











