RSA私钥解包失败:DOMException错误排查求助
问题:解包加密的RSA私钥时抛出DOMException错误
尝试通过用户密码派生的AES密钥加密RSA私钥,在解包时出现错误:DOMException: An invalid or illegal string was specified。
错误原因
RSA-OAEP算法的私钥仅支持decrypt和unwrapKey两种密钥用法,代码中在调用unwrapKey时,为私钥指定了不支持的encrypt用法,导致参数非法。
修复方案
将unwrapKey调用的最后一个参数(密钥用法数组)从["encrypt", "decrypt"]修改为["decrypt"],匹配RSA私钥的合法用法。
修复后的完整代码
const base64ToArrayBuffer = (data) => { const binaryKey = atob(data); const keyBytes = new Uint8Array(binaryKey.length); for (let i = 0; i < binaryKey.length; i++) { keyBytes[i] = binaryKey.charCodeAt(i); } return keyBytes.buffer; } const bufferToBase64 = (data) => btoa(String.fromCharCode(... new Uint8Array(data))); const fn = async () => { // Generate RSA key pair const keyPair = await crypto.subtle.generateKey({ name: "RSA-OAEP", modulusLength: 4096, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-512" }, true, ["encrypt", "decrypt"]); // Encrypt the private key const textEncoder = new TextEncoder(); const salt = new Uint8Array(16); crypto.getRandomValues(salt); const passwordKey = await crypto.subtle.importKey("raw", textEncoder.encode(window.prompt("password")), "PBKDF2", true, ["deriveKey"]); const derivedKey = await crypto.subtle.deriveKey({ name: "PBKDF2", hash: "SHA-256", salt, iterations: 210000 }, passwordKey, { name: "AES-CBC", length: 256 }, true, ["wrapKey", "unwrapKey"]); const iv = new Uint8Array(16); crypto.getRandomValues(iv); const wrappedPrivateKey = await crypto.subtle.wrapKey("pkcs8", keyPair.privateKey, derivedKey, { name: "AES-CBC", iv }); const b64WrappedPrivateKey = bufferToBase64(wrappedPrivateKey); const b64Salt = bufferToBase64(salt); const b64IV = bufferToBase64(iv); const encryptedPrivateKey = base64ToArrayBuffer(b64WrappedPrivateKey); const unwrapSalt = base64ToArrayBuffer(b64Salt); const unwrapIV = base64ToArrayBuffer(b64IV); const unwrapPasswordKey = await crypto.subtle.importKey("raw", textEncoder.encode(window.prompt("password unwrap")), "PBKDF2", true, ["deriveKey"]); const unwrappingKey = await crypto.subtle.deriveKey({ name: "PBKDF2", hash: "SHA-256", salt: unwrapSalt, iterations: 210000 }, unwrapPasswordKey, { name: "AES-CBC", length: 256 }, true, ["wrapKey", "unwrapKey"]); try { const privateKey = await crypto.subtle.unwrapKey("pkcs8", encryptedPrivateKey, unwrappingKey, { name: "AES-CBC", iv: unwrapIV }, { name: "RSA-OAEP", hash: "SHA-512" }, true, ["decrypt"]); // 此处修改为仅允许decrypt用法 console.log("Success"); } catch (err) { console.log(err); } }; (async () => { await fn(); })()
内容的提问来源于stack exchange,提问作者iKingNinja
相关产品推荐
相关产品推荐

