Web Crypto API中wrapKey用公钥加密公钥触发OperationError的问题排查
Web Crypto API中wrapKey用公钥加密公钥触发OperationError的问题排查
我来帮你排查这个问题,你遇到的无详情OperationError其实是几个参数配置错误导致的,咱们一步步拆解:
1. 密钥用法(keyUsages)配置不规范
你在生成密钥时给公钥指定了它根本不支持的权限,这会导致密钥对象状态异常:
- 生成
wrappingKey(用于包装的公钥)时,你传入的keyUsages包含decrypt和unwrapKey,但RSA公钥只支持encrypt和wrapKey操作,decrypt和unwrapKey都是私钥的专属权限。虽然Web Crypto会自动过滤掉公钥不支持的用法,但这种不规范的配置很容易触发隐性错误。正确的做法是,生成用于包装的密钥对时,只传入合法的用法组合,比如['wrapKey', 'unwrapKey']——这样公钥会自动获取wrapKey权限,私钥获取unwrapKey权限。 - 生成
myKey(要被包装的公钥)时,你给它指定了['encrypt', 'decrypt'],同样,公钥不支持decrypt,这里应该只传['encrypt'](如果这个公钥之后还要用来包装其他密钥,可以加wrapKey)。
2. wrapKey的算法参数冗余
你调用wrapKey时,第四个参数传入了完整的RSA-OAEP配置(包括modulusLength和publicExponent),但这些是密钥生成阶段的参数,不是包装操作需要的算法参数。Web Crypto会校验算法参数与wrappingKey的属性是否匹配,多余的参数会导致算法不匹配,直接抛出OperationError。
对于RSA-OAEP的wrap操作,算法参数只需要指定name和hash就足够了——这些信息已经包含在wrappingKey这个CryptoKey对象里,完全不需要重复传入。
修正后的代码示例
把这些问题都修正后,代码应该是这样的:
// 生成用于包装的密钥对,公钥负责wrapKey,私钥负责unwrapKey const {publicKey: wrappingKey} = await window.crypto.subtle.generateKey( {name: 'RSA-OAEP', modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256'}, true, ['wrapKey', 'unwrapKey']); // 生成要被包装的密钥对,公钥只保留合法的encrypt权限 const {publicKey: myKey} = await window.crypto.subtle.generateKey( {name: 'RSA-OAEP', modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256'}, true, ['encrypt']); try { // 修正算法参数,只保留必要的name和hash const output = await window.crypto.subtle.wrapKey( 'jwk', myKey, wrappingKey, {name: 'RSA-OAEP', hash: 'SHA-256'} ); console.log(output); } catch (e) { console.log(e); }
这样修改后,应该就能正常执行wrap操作了,你可以在Chrome里测试一下,不会再抛出无详情的错误了。
备注:内容来源于stack exchange,提问作者Jonah
相关产品推荐
相关产品推荐

