我有代码加密用户的数据使用CryptoJS.AES,存储密钥,iv和加密的内容在不同的地方。它还使用存储的密钥和用户要求的iv来解密加密的内容。
我想使用微妙的加密浏览器API加密,这是完成的。
但我也想有可能解密旧数据(这是使用CryptoJS.AES加密)使用微妙的加密。
旧数据是用以下代码生成的
var CryptoJS = require("crypto-js/core");
CryptoJS.AES = require("crypto-js/aes");
let encKey = generateRandomString();
let aesEncrypted = CryptoJS.AES.encrypt(content, encKey);
let encrypted = {
key: aesEncrypted.key.toString(),
iv: aesEncrypted.iv.toString(),
content: aesEncrypted.toString()
};我试着把它解密如下
let keyArrayBuffer = hexArrayToArrayBuffer(sliceArray(encrypted.key, 2));
let decKey = await importKey(keyArrayBuffer);
let decIv = hexArrayToArrayBuffer(sliceArray(encrypted.iv, 2));
let encContent = stringToArrayBuffer(encrypted.content);
let decryptedByteArray = await crypto.subtle.decrypt(
{ name: "AES-CBC", iv: decIv },
decKey,
encContent
);
let decrypted = new TextDecoder().decode(decrypted);我在await crypto.subtle.decrypt上收到无回溯的DOMException错误
完整的复制可以在https://codesandbox.io/s/crypto-js-to-subtle-crypto-u0pgs?file=/src/index.js上找到。
发布于 2020-09-26 02:09:21
在CryptoJS代码中,键作为字符串传递。因此,它被解释为密码,从该密码与随机生成的8字节salt、32字节密钥和16字节IV一起导出,参见here。专有的(且相对不安全的) OpenSSL密钥导出函数EVP_BytesToKey用于此目的。
CryptoJS.AES.encrypt()返回一个CipherParams对象,该对象封装了各种参数,例如生成的键和作为WordArray的IV,请参见here。应用于密钥或IV WordArray的toString()将返回十六进制编码的数据。toString()应用于CipherParams对象,返回OpenSSL格式的密文,即第一个块(=前16个字节)由Salted__的ASCII码组成,然后是8字节的salt和实际密文,所有这些都是Base64编码的,请参阅here。这意味着实际的密文(在Base64解码之后)从第二个块开始。
以下代码说明了如何使用WebCrypto应用编程接口解密使用CryptoJS生成的密文
//
// CryptoJS
//
const content = "The quick brown fox jumps over the lazy dog";
const encKey = "This is my passphrase";
const aesEncrypted = CryptoJS.AES.encrypt(content, encKey);
const encrypted = {
key: aesEncrypted.key.toString(),
iv: aesEncrypted.iv.toString(),
content: aesEncrypted.toString()
};
//
// WebCrypto API
//
// https://stackoverflow.com/a/50868276
const fromHex = hexString => new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
// https://stackoverflow.com/a/41106346
const fromBase64 = base64String => Uint8Array.from(atob(base64String), c => c.charCodeAt(0));
async function decryptDemo(){
const rawKey = fromHex(encrypted.key);
const iv = fromHex(encrypted.iv);
const ciphertext = fromBase64(encrypted.content).slice(16);
const key = await window.crypto.subtle.importKey(
"raw",
rawKey,
"AES-CBC",
true,
["encrypt", "decrypt"]
);
const decrypted = await window.crypto.subtle.decrypt(
{
name: "AES-CBC",
iv: iv
},
key,
ciphertext
);
const decoder = new TextDecoder();
const plaintext = decoder.decode(decrypted);
console.log(plaintext);
}
decryptDemo();<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
https://stackoverflow.com/questions/64067812
复制相似问题