簡體   English   中英

window.crypto 返回 352 位密鑰而不是 256?

[英]window.crypto returns 352 bit key instead of 256?

我正在嘗試使用window.crypto加密一些文本:

await crypto.subtle.encrypt(algorithm, key, dataArrayBuffer).catch(error => console.error(error));

但是我得到這個錯誤AES key data must be 128 or 256 bits 我正在使用 PBKDF2 從密碼創建一個 256 位密鑰,並指定密鑰長度為256

window.crypto.subtle.deriveKey(
            {
                "name": "PBKDF2",
                "salt": salt,
                "iterations": iterations,
                "hash": hash
            },
            baseKey,
            {"name": "AES-GCM", "length": 256}, //<------------
            true, 
            ["encrypt", "decrypt"]
            );

但是我最終得到了這個密鑰edi5Fou4yCdSdx3DX3Org+L2XFAsVdomVgpVqUGjJ1g=在我exportKey並將其從ArrayBuffer轉換為長度為44字節和352位的string之后......

這可以解釋錯誤,但是如何從window.cryptoPBKDF2創建一個實際的256位密鑰?

JSFiddle: https://jsfiddle.net/6Lyaoudc/1/

顯示的長度是指 Base64 編碼密鑰。 根據顯示的值,32 字節密鑰的 Base64 編碼長度為 44 字節(352 位),因此是正確的,請參見此處的示例。

錯誤在於,在第二個importKey中(請參閱從 import 為 AES-GCM 創建 CryptoKey 的注釋),傳遞的是 Base64 編碼的密鑰(即keyString )而不是二進制密鑰(即ArrayBuffer keyBytes )。 如果keyBytes被傳遞,加密工作:

 function deriveAKey(password, salt, iterations, hash) { // First, create a PBKDF2 "key" containing the password window.crypto.subtle.importKey( "raw", stringToArrayBuffer(password), {"name": "PBKDF2"}, false, ["deriveKey"]). then(function(baseKey){ // Derive a key from the password return window.crypto.subtle.deriveKey( { "name": "PBKDF2", "salt": salt, "iterations": iterations, "hash": hash }, baseKey, {"name": "AES-GCM", "length": 256}, // Key we want.Can be any AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC") true, // Extractable ["encrypt", "decrypt"] // For new key ); }).then(function(aesKey) { // Export it so we can display it return window.crypto.subtle.exportKey("raw", aesKey); }).then(async function(keyBytes) { // Display key in Base64 format var keyS = arrayBufferToString(keyBytes); var keyB64 = btoa (keyS); console.log(keyB64); console.log('Key byte size: ', byteCount(keyB64)); console.log('Key bit size: ', byteCount(keyB64) * 8); var keyString = stringToArrayBuffer(keyB64); const iv = window.crypto.getRandomValues(new Uint8Array(12)); const algorithm = { name: 'AES-GCM', iv: iv, }; //Create CryptoKey for AES-GCM from import const key = await crypto.subtle.importKey( 'raw',//Provided key will be of type ArrayBuffer // keyString, keyBytes, // 1. Use keyBytes instead of keyString { name: "AES-GCM", }, false,//Key not extractable ['encrypt', 'decrypt'] ); //Convert data to ArrayBuffer var data = "The quick brown fox jumps over the lazy dog"; // 2. Define data const dataArrayBuffer = new TextEncoder().encode(data); const encryptedArrayBuffer = await crypto.subtle.encrypt(algorithm, key, dataArrayBuffer).catch(error => console.error(error)); var ivB64 = btoa(arrayBufferToString(iv)); console.log(ivB64); // 3. Display (Base64 encoded) IV var encB64 = btoa(arrayBufferToString(encryptedArrayBuffer)); console.log(encB64.replace(/(.{56})/g,'$1\n')); // 4. Display (Base64 encoded) ciphertext (different for each encryption, because of random salt and IV) }).catch(function(err) { console.error("Key derivation failed: " + err.message); }); } //Utility functions function stringToArrayBuffer(byteString){ var byteArray = new Uint8Array(byteString.length); for(var i=0; i < byteString.length; i++) { byteArray[i] = byteString.codePointAt(i); } return byteArray; } function arrayBufferToString(buffer){ var byteArray = new Uint8Array(buffer); var byteString = ''; for(var i=0; i < byteArray.byteLength; i++) { byteString += String.fromCodePoint(byteArray[i]); } return byteString; } function byteCount(s) { return encodeURI(s).split(/%..|./).length - 1; } var salt = window.crypto.getRandomValues(new Uint8Array(16)); var iterations = 5000; var hash = "SHA-512"; var password = "password"; deriveAKey(password, salt, iterations, hash);

除了密鑰,代碼還顯示IV和密文,每個Base64編碼。 例如可以使用 Base64 編碼的密鑰和 IV 來驗證密文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM