英文:
JavaScript WebCryptoApi: Why does this not satisfy operation specific requirements?
问题
以下是翻译好的部分:
设置:
- 我生成了一个密钥加密密钥(kek,AES-GCM,256位)
- 我生成了一个RSA-OAEP密钥对
- 我使用AES-GCM-256和一个随机的iv来包装生成的私钥,以pkcs8格式导出
- 我尝试解包装密钥,但在“导入”阶段失败
控制台显示的错误消息是“DOMException:提供给操作的数据不符合要求”,我已经创建了以下的MWE:
<!-- 开始代码片段:js 隐藏:false 控制台:true Babel:false -->
<!-- 语言:lang-js -->
(async() => {
let exportFormat = "pkcs8";
const keyWrappingAlgorithm = {
name: "AES-GCM",
length: 256,
}
let keyPairAlgorithm = {
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
};
let kek = await window.crypto.subtle.generateKey(
keyWrappingAlgorithm,
true,
["decrypt", "wrapKey", "unwrapKey"]
);
let keyPair = await crypto.subtle.generateKey(
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
)
const iv = crypto.getRandomValues(new Uint8Array(96/8));
let wrappedPrivateKey = await crypto.subtle.wrapKey(
exportFormat,
keyPair.privateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
}
)
let decryptedData = await crypto.subtle.decrypt(
{
...keyWrappingAlgorithm,
iv: iv,
},
kek,
wrappedPrivateKey,
)
console.log("done 1", decryptedData)
await crypto.subtle.importKey(
exportFormat,
decryptedData,
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
).then(() => {
console.log("Success 1! This was not expected.")
}).catch((error) => console.log("error 1", error))
let unwrappedKey = await crypto.subtle.unwrapKey(
exportFormat,
wrappedPrivateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
},
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
).then(() => {
console.log("Success 2! This was not expected.")
}).catch((error) => console.log("error 2", error))
})()
<!-- 结束代码片段 -->
发生了什么?如何纠正这种行为以解包装包装的密钥?
我已经坐在这里至少2个小时了,提取了MWE,但错误消息没有提供太多信息。我尝试更改导出格式,但没有真正帮助。所有密钥都是可导出的,所以这不应该是个问题。我也认为我已经添加了所有必需的密钥用途。
请注意,我已经去掉了代码部分,只提供了文本内容的翻译。如果需要更多帮助或有其他问题,请随时提出。
英文:
Setup:
- I generate a key-encryption-key (kek, AES-GCM, 256)
- I generate a RSA-OAEP keypair
- I wrap the generated private key with the kek using AES-GCM-256 and a random iv, exported as pkcs8
- I try to unwrap the key, this fails at the "import" stage
The error message shown in the console is "DOMException: Data provided to an operation does not meet requirements", I have managed to create a MWE as follows:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
(async() => {
let exportFormat = "pkcs8";
const keyWrappingAlgorithm = {
name: "AES-GCM",
length: 256,
}
let keyPairAlgorithm = {
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
};
let kek = await window.crypto.subtle.generateKey(
keyWrappingAlgorithm,
true,
["decrypt", "wrapKey", "unwrapKey"]
);
let keyPair = await crypto.subtle.generateKey(
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
)
const iv = crypto.getRandomValues(new Uint8Array(96/8));
let wrappedPrivateKey = await crypto.subtle.wrapKey(
exportFormat,
keyPair.privateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
}
)
let decryptedData = await crypto.subtle.decrypt(
{
...keyWrappingAlgorithm,
iv: iv,
},
kek,
wrappedPrivateKey,
)
console.log("done 1", decryptedData)
await crypto.subtle.importKey(
exportFormat,
decryptedData,
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
).then(() => {
console.log("Success 1! This was not expected.")
}).catch((error) => console.log("error 1", error))
let unwrappedKey = await crypto.subtle.unwrapKey(
exportFormat,
wrappedPrivateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
},
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
).then(() => {
console.log("Success 2! This was not expected.")
}).catch((error) => console.log("error 2", error))
})()
<!-- end snippet -->
What is going on here? How can I correct this behavior and unwrap the wrapped key?
I've been sitting at this for at least 2 hours by now to extract the MWE, but the error message doesn't give much information. I tried changing the export format, but that didn't really help. The keys all are exportable, so this shouldn't be an issue either. I also think that I added all the required key usages..
答案1
得分: 2
以下是翻译好的部分:
对于RSA-OAEP,私钥只能用于解密(加密需要使用公钥),即必须使用`["decrypt"]`作为*keyUsages*,而不是`["encrypt", "decrypt"]`。错误消息*...无法使用指定的密钥用途创建密钥...*指出了这一点。
如果在`importKey()`和`unwrapKey()`中应用`["decrypt"]`作为*keyUsages*,导入和解包将正常工作:
(async() => {
let exportFormat = "pkcs8";
const keyWrappingAlgorithm = {
name: "AES-GCM",
length: 256,
}
let keyPairAlgorithm = {
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
};
let kek = await window.crypto.subtle.generateKey(
keyWrappingAlgorithm,
true,
["decrypt", "wrapKey", "unwrapKey"]
);
let keyPair = await crypto.subtle.generateKey(
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
)
const iv = crypto.getRandomValues(new Uint8Array(96/8));
let wrappedPrivateKey = await crypto.subtle.wrapKey(
exportFormat,
keyPair.privateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
}
)
let decryptedData = await crypto.subtle.decrypt(
{
...keyWrappingAlgorithm,
iv: iv,
},
kek,
wrappedPrivateKey,
)
let decryptedKey = await crypto.subtle.importKey(
exportFormat,
decryptedData,
keyPairAlgorithm,
true,
["decrypt"]
)
console.log(decryptedKey);
console.log(ab2hex(await crypto.subtle.exportKey('pkcs8', decryptedKey)));
let unwrappedKey = await crypto.subtle.unwrapKey(
exportFormat,
wrappedPrivateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
},
keyPairAlgorithm,
true,
["decrypt"]
)
console.log(unwrappedKey);
console.log(ab2hex(await crypto.subtle.exportKey('pkcs8', unwrappedKey)));
})()
function ab2hex(ab) {
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
}
希望对你有所帮助!
英文:
For RSA-OAEP a private key can only be used for decryption (encryption is done with the public key), i.e. for keyUsages ["decrypt"]
has to be used and not ["encrypt", "decrypt"]
. The error message ...Cannot create a key using the specified key usages... points this out.
If you apply ["decrypt"]
as keyUsages in importKey()
and unwrapKey()
the importing and unwrapping works:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
(async() => {
let exportFormat = "pkcs8";
const keyWrappingAlgorithm = {
name: "AES-GCM",
length: 256,
}
let keyPairAlgorithm = {
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
};
let kek = await window.crypto.subtle.generateKey(
keyWrappingAlgorithm,
true,
["decrypt", "wrapKey", "unwrapKey"]
);
let keyPair = await crypto.subtle.generateKey(
keyPairAlgorithm,
true,
["encrypt", "decrypt"]
)
const iv = crypto.getRandomValues(new Uint8Array(96/8));
let wrappedPrivateKey = await crypto.subtle.wrapKey(
exportFormat,
keyPair.privateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
}
)
let decryptedData = await crypto.subtle.decrypt(
{
...keyWrappingAlgorithm,
iv: iv,
},
kek,
wrappedPrivateKey,
)
let decryptedKey = await crypto.subtle.importKey(
exportFormat,
decryptedData,
keyPairAlgorithm,
true,
["decrypt"]
)
console.log(decryptedKey);
console.log(ab2hex(await crypto.subtle.exportKey('pkcs8', decryptedKey)));
let unwrappedKey = await crypto.subtle.unwrapKey(
exportFormat,
wrappedPrivateKey,
kek,
{
...keyWrappingAlgorithm,
iv: iv,
},
keyPairAlgorithm,
true,
["decrypt"]
)
console.log(unwrappedKey);
console.log(ab2hex(await crypto.subtle.exportKey('pkcs8', unwrappedKey)));
})()
function ab2hex(ab) {
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
}
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论