将字符串格式公钥转为SubtleCrypto的CryptoKey解决加密参数错误
解决SubtleCrypto加密时"parameter 2 is not of type 'CryptoKey'"错误
这个错误的核心原因很直接:crypto.subtle.encrypt方法的第二个参数必须是CryptoKey对象,而你传入的是原始字符串格式的公钥,SubtleCrypto无法直接识别。你需要先把字符串公钥转换成符合要求的CryptoKey对象,再传入加密方法。
具体解决步骤
- 处理PEM格式公钥:如果你的公钥是常见的PEM格式(带
-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----头尾),先去掉这些标识行,再将剩余的Base64字符串转换成ArrayBuffer。 - 导入公钥为CryptoKey:使用
crypto.subtle.importKey方法,将处理后的公钥数据导入成可用于RSA-OAEP加密的CryptoKey对象。
修正后的完整代码
const handleEncodeClick = async () => { const crypto = window.crypto.subtle; try { // 1. 处理字符串公钥(以PEM格式为例) const pemPublicKey = publicKey; // 你的字符串公钥 const strippedKey = pemPublicKey .replace(/-----BEGIN PUBLIC KEY-----/g, '') .replace(/-----END PUBLIC KEY-----/g, '') .replace(/\s/g, ''); // 去掉所有空白字符 const keyBuffer = Uint8Array.from(atob(strippedKey), c => c.charCodeAt(0)); // 2. 导入公钥为CryptoKey对象 const cryptoKey = await crypto.importKey( 'spki', // 公钥使用SPKI格式 keyBuffer, { name: 'RSA-OAEP', hash: 'SHA-256' // 注意这里要和生成公钥时使用的哈希算法一致,常用SHA-256 }, false, // 公钥不可提取 ['encrypt'] // 只赋予加密用途 ); // 3. 执行加密 const encrypted = await crypto.encrypt( { name: 'RSA-OAEP' }, cryptoKey, new TextEncoder().encode(myMsg) ); setEncoded(new Uint8Array(encrypted)); } catch (err) { console.error('加密失败:', err); } };
注意事项
- 如果你的公钥是JWK格式(JSON Web Key),可以把
importKey的第一个参数改成'jwk',并传入解析后的JSON对象即可。 - 导入公钥时的哈希算法(比如SHA-256)必须和生成该公钥时使用的哈希算法完全一致,否则会导入失败。
内容的提问来源于stack exchange,提问作者m0j1
相关产品推荐
相关产品推荐

