解决Cryptico.js RSA私钥导入browser.subtle的JWK解码报错问题
解决Cryptico.js RSA私钥导入browser.subtle的问题
问题描述
尝试将Cryptico.js生成的RSA私钥提取后导入browser.subtle,已添加decimalToBase64url函数处理密钥参数,但控制台提示错误:
"The JWK member "n" could not be base64url decoded or contained padding"
错误原因
原decimalToBase64url函数存在两个关键问题:
- 十六进制字符串长度可能为奇数,导致
Uint8Array构造失败(最后一个单字符十六进制无法正确转成字节) - 转换后的base64url未移除末尾的填充字符
=,而JWK规范要求base64url编码不能包含填充 - 额外问题:JWK字段名不符合规范,原代码中
dmp1/dmq1/coeff对应的标准字段名应为dp/dq/qi
解决方案
1. 修正decimalToBase64url函数
确保十六进制字符串长度为偶数,并移除base64的填充字符:
function decimalToBase64url(decimal) { // 将BigInteger转为十六进制字符串,补前导零确保长度为偶数 let hexString = decimal.toString(16); if (hexString.length % 2 !== 0) { hexString = '0' + hexString; } // 十六进制转Uint8Array const uint8Array = new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16))); // Uint8Array转base64,再转base64url并移除填充 const base64 = btoa(String.fromCharCode.apply(null, uint8Array)); return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); }
2. 完整修正后的转换函数
async function convertCrypticoToCryptoKeyPair(crypticoKey) { const n = decimalToBase64url(crypticoKey.n); const e = decimalToBase64url(crypticoKey.e); const d = decimalToBase64url(crypticoKey.d); const p = decimalToBase64url(crypticoKey.p); const q = decimalToBase64url(crypticoKey.q); const dp = decimalToBase64url(crypticoKey.dmp1); const dq = decimalToBase64url(crypticoKey.dmq1); const qi = decimalToBase64url(crypticoKey.coeff); const jwkPrivateKey = { kty: "RSA", n, e, d, p, q, dp, dq, qi, }; const privateKey = await crypto.subtle.importKey( "jwk", jwkPrivateKey, { name: "RSA-PSS", hash: { name: "SHA-256" } }, true, ["sign"] ); const publicKey = await crypto.subtle.importKey( "jwk", { kty: "RSA", n, e }, { name: "RSA-PSS", hash: { name: "SHA-256" } }, true, ["verify"] ); return { privateKey, publicKey }; } // 测试代码 const PassPhrase = "your_passphrase"; const Bits = 2048; const crypticoRSAKey = cryptico.generateRSAKey(PassPhrase, Bits); convertCrypticoToCryptoKeyPair(crypticoRSAKey).then((keyPair) => { console.log("转换成功的CryptoKeyPair:", keyPair); }).catch(err => { console.error("转换失败:", err); });
3. Cryptico.js扩展代码(参考)
// Export RSA key@furkan-bilgin my.exportRSAKey = function(rsaKey) { return JSON.stringify(rsaKey); } /* method 2 Hex @zwisler-a function serializeRSAKey(key) { return JSON.stringify({ coeff: key.coeff.toString(16), d: key.d.toString(16), dmp1: key.dmp1.toString(16), dmq1: key.dmq1.toString(16), e: key.e.toString(16), n: key.n.toString(16), p: key.p.toString(16), q: key.q.toString(16) }) } */
内容的提问来源于stack exchange,提问作者Ka Fong
相关产品推荐
相关产品推荐

