如何让SubtleCrypto加密数据可被Node.js crypto.privateDecrypt解密?
解决SubtleCrypto RSA-OAEP加密与Node.js crypto.privateDecrypt兼容问题
问题根源
出现Error:02000079:rsa routines::oaep decoding error的核心原因是客户端与服务器端的RSA-OAEP参数不匹配,结合你的代码,主要存在以下几个问题:
修复步骤
1. 修正算法名称的笔误
你的asymmetricEncryptStringKey函数中,encrypt配置的name字段错误使用了字符串字面量'ASYMMETRIC_ALGORITHM',而非定义好的常量。这会导致SubtleCrypto使用错误的加密算法,直接引发解密失败。
修复后的代码片段:
const encryptedArrayBuffer = await webcryptoAPI.subtle.encrypt( { name: ASYMMETRIC_ALGORITHM, // 去掉引号,使用定义好的常量 }, key, encoded );
2. 对齐哈希算法(关键)
Node.js的crypto.privateDecrypt默认使用SHA-1作为RSA-OAEP的哈希函数,而你的客户端代码指定了SHA-256。由于无法修改服务器代码,必须将客户端的哈希算法调整为SHA-1以匹配服务器默认配置:
修改importAsymmetricPublicKey函数中的哈希配置:
return await webcryptoAPI.subtle.importKey( 'spki', Buffer.from(publicKeyBase64, ENCODING), { name: ASYMMETRIC_ALGORITHM, hash: 'SHA-1' }, // 改为SHA-1 true, ['encrypt'] );
3. 移除冗余的模数长度参数
导入公钥时,modulusLength是生成密钥对时的参数,导入SPKI格式的公钥时不需要指定,冗余参数可能导致解析异常,直接删除即可:
// 移除原代码中的modulusLength: 4096参数 { name: ASYMMETRIC_ALGORITHM, hash: 'SHA-1' },
完整修复后的客户端代码
const ASYMMETRIC_ALGORITHM = 'RSA-OAEP'; const ENCODING = 'base64'; async function importAsymmetricPublicKey(secretKey) { try { const publicKeyPEM = secretKey .replace(/-----BEGIN PUBLIC KEY-----/, '') .replace(/-----END PUBLIC KEY-----/, ''); const publicKeyBase64 = publicKeyPEM.replace(/\r\n|\n|\r/g, ''); return await webcryptoAPI.subtle.importKey( 'spki', Buffer.from(publicKeyBase64, ENCODING), { name: ASYMMETRIC_ALGORITHM, hash: 'SHA-1' }, true, ['encrypt'] ); } catch (error) { console.log('[importAsymmetricPublicKey]: ', error); } } async function asymmetricEncryptStringKey(publicKey, generatedKey) { const key = await importAsymmetricPublicKey(publicKey); let encoded = encodeMessage(generatedKey); const encryptedArrayBuffer = await webcryptoAPI.subtle.encrypt( { name: ASYMMETRIC_ALGORITHM, }, key, encoded ); return Buffer.from(encryptedArrayBuffer); }
验证逻辑
修复后,客户端加密的数据会使用与服务器端匹配的RSA-OAEP参数(SHA-1哈希、正确算法名称),确保crypto.privateDecrypt可以正常解密。
内容的提问来源于stack exchange,提问作者kevin parra
相关产品推荐
相关产品推荐

