<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<script>
let intermediateKey;
let publicKey;
let privateKey;
let wrappedKey;
let iv;
async function rsaKeyPair() {
let keyPair = await crypto.subtle.generateKey({
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
},
true, ["wrapKey", "unwrapKey"]
);
publicKey = keyPair.publicKey;
privateKey = keyPair.privateKey;
}
async function encrypt(secret) {
// generating random intermediate key to encrypt and decrypt the secret
intermediateKey = await crypto.subtle.generateKey({
name: "AES-GCM",
length: 256
},
true, ["encrypt", "decrypt"]
);
// encrypt secret
// ...
// wrap intermediate key (export + encrypt) intermediateKey using publicKey.
iv = crypto.getRandomValues(new Uint8Array(12));
wrappedKey = await crypto.subtle.wrapKey(
"jwk",
intermediateKey,
publicKey, {
name: "AES-GCM",
iv: iv
}
);
}
async function decrypt(cipher) {
// unwrap (decrypt + import) aes key using private key.
intermediateKey = await crypto.subtle.unwrapKey(
"jwk",
wrappedKey,
privateKey, {
name: "AES-GCM",
iv: iv
}, {
name: "AES-GCM"
},
false, ["encrypt", "decrypt"]
);
// decrypt the cipher
// ...
}
async function solve() {
// generate rsa-keypairs
await rsaKeyPair();
// encrypt secret
const cipher = await encrypt("secret");
// decrypt cipher
await decrypt(cipher);
}
solve();
</script>
</body>
</html>
生成RSA-OAEP密钥对(根据http://www.w3.org/TR/WebCryptoAPI/#algorithm-overview.)
当用户创建秘密时,该秘密将使用AES-GCM-256和随机生成的中间密钥进行加密。最后,用用户的公钥包装这个中间密钥。
最后,解开中间密钥&解密。
该错误是在解开中间密钥期间产生的。
发布于 2021-01-25 03:25:25
wrapKey()和unwrapKey()调用分别缺少wrapAlgo和unwrapAlgo参数的适当规范,这两个参数用于指定加密密钥的算法。在本例中,应用了带有OAEP的RSA,因此两个参数都必须使用RsaOaepParams对象。
如果在两个函数中都正确指定了参数,则AES密钥将被正确加密和解密:
let intermediateKey;
let publicKey;
let privateKey;
let wrappedKey;
let iv;
async function rsaKeyPair() {
let keyPair = await crypto.subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256',
},
true,
['wrapKey', 'unwrapKey']
);
publicKey = keyPair.publicKey;
privateKey = keyPair.privateKey;
}
async function encrypt() {
// Generate AES key
intermediateKey = await crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 256
},
true,
['encrypt', 'decrypt']
);
// Encrypt secret
// ...
// Wrap AES key
/*
iv = crypto.getRandomValues(new Uint8Array(12));
wrappedKey = await crypto.subtle.wrapKey(
'jwk',
intermediateKey,
publicKey,
{
name: "AES-GCM",
iv: iv
}
);
*/
wrappedKey = await crypto.subtle.wrapKey(
'raw',
intermediateKey,
publicKey,
{ // wrapAlgo, here an RsaOaepParams object, s. https://developer.mozilla.org/en-US/docs/Web/API/RsaOaepParams
name: 'RSA-OAEP'
}
);
console.log('Wrapped AES key: ', new Uint8Array(wrappedKey));
}
async function decrypt() {
// Unwrap AES key
/*
intermediateKey = await crypto.subtle.unwrapKey(
'jwk',
wrappedKey,
privateKey,
{
name: "AES-GCM",
iv: iv
},
{
name: "AES-GCM"
},
false,
["encrypt", "decrypt"]
);
*/
intermediateKey = await crypto.subtle.unwrapKey(
'raw',
wrappedKey,
privateKey,
{ // unwrapAlgo, here an RsaOaepParams object, s. https://developer.mozilla.org/en-US/docs/Web/API/RsaOaepParams
name: 'RSA-OAEP'
},
{
name: 'AES-GCM'
},
false, ['encrypt', 'decrypt']
);
console.log('Unwrapped AES key: ', intermediateKey);
// Decrypt ciphertext
// ...
}
async function solve() {
await rsaKeyPair();
await encrypt();
await decrypt();
}
solve();
https://stackoverflow.com/questions/65871725
复制相似问题