使用window.crypto.subtle API从浏览器解密AES-CTR 256位消息

时间:2020-04-02 17:11:48

标签: javascript encryption aes window.crypto

我需要在浏览器中解密使用AES-CTR 256位(使用OpenSSL编码)编码的消息。

使用OpenSSL,我得到类似的东西:

key=189BBBB00C5F1FB7FBA9AD9285F193D1771D7611CB891E5C1F4E24C20E50FB1D
iv =4103C88663AE12CE18EA46E894280C4D
msg=nhVKeu8zNO2PRTwJrDE=

好吧,我的问题是将这些字符串转换为window.crypto.subtle API可以管理的对象。例如

const counter = ???;
const ciphertext = ???;
const rawKey = ???;

const key = window.crypto.subtle.importKey(
    "raw",
    key,
    "AES-CTR",
    true,
    ["encrypt", "decrypt"]
);

const decrypted = await window.crypto.subtle.decrypt(
{
    name: "AES-CTR",
    counter,
    length: 64
  },
  key,
  ciphertext
);

let dec = new TextDecoder();
const msg = dec.decode(decrypted);
console.log(msg);

有人可以帮助我从keyivmsg转到counterciphertextrawkey吗?

非常感谢

1 个答案:

答案 0 :(得分:1)

密钥,计数器(或IV)和密文可以作为 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script> <script src="test.js"></script> 传递,即您需要进行两次转换,一次转换为十六进制,第二次转换为从Base64编码的字符串转换为TypedArray,例如

来自十六进制编码的字符串here

TypedArray

来自Base64编码的字符串here

const fromHex = hexString => new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));

在代码本身中缺少const fromBase64 = base64String => Uint8Array.from(atob(base64String), c => c.charCodeAt(0)); 运算符,并且在await函数importKey中必须使用rawKey来代替(可能是复制/粘贴错误)。一起:

key

这会将密文解密为:

const fromHex = hexString => new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
const fromBase64 = base64String => Uint8Array.from(atob(base64String), c => c.charCodeAt(0));
		
async function test(){
		
    const rawKey = fromHex("189BBBB00C5F1FB7FBA9AD9285F193D1771D7611CB891E5C1F4E24C20E50FB1D");
    const counter = fromHex("4103C88663AE12CE18EA46E894280C4D");
    const ciphertext = fromBase64("nhVKeu8zNO2PRTwJrDE=");

    const key = await window.crypto.subtle.importKey(   // add >await<
        "raw",
        rawKey,                                         // replace >key< with >rawKey<
        "AES-CTR",
        true,
        ["encrypt", "decrypt"]
    );

    const decrypted = await window.crypto.subtle.decrypt(
        {
            name: "AES-CTR",
            counter,
            length: 64
        },
        key,
        ciphertext
    );

    let dec = new TextDecoder();
    const msg = dec.decode(decrypted);
    console.log(msg);
}

test();