JavaScript AES-GCM的Python解密后的跟踪垃圾



我将JavaScript绑定到一个HTMl按钮,该按钮执行AES-GCM编码并将有用的信息记录到控制台。

function strToArrayBuffer(str) {
let buf = new ArrayBuffer(str.length * 2);
let bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
function arrayBufferToString(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function arrayBufferToHex(buf) {
return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, "0")).join("");
}
let iv = window.crypto.getRandomValues(new Uint8Array(12));
console.log('nonce/iv: ' + arrayBufferToHex(iv));
let algoEncrypt = {
name: 'AES-GCM',
iv: iv,
tagLength: 128
};
let plainText =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer imperdiet pretium leo, et auctor velit fermentum nec. Mauris eu finibus orci.";
console.log('Input Text: ' + plainText);
let secretKey = null;
window.crypto.subtle.generateKey(
{name: 'AES-GCM', length: 256},
true,
['encrypt', 'decrypt']
).then(function (key) {
secretKey = key;
return window.crypto.subtle.encrypt(algoEncrypt, key, strToArrayBuffer(plainText));
}).then(function (cipherText) {
console.log('Encrypted Hex:n' + arrayBufferToHex(cipherText));
return window.crypto.subtle.decrypt(algoEncrypt, secretKey, cipherText);
}).then(function (newPlainText) {
if (arrayBufferToString(newPlainText) == plainText) {
console.log("decryption matches");
} else {
console.log("decryption ERROR:" + arrayBufferToHex(newPlainText));
}
return window.crypto.subtle.exportKey("raw", secretKey);
}).then(function (keyData) {
console.log('Password Hex:n' + arrayBufferToHex(keyData));
}).catch(function (err) {
console.log('Error: ' + err.message);
});

示例控制台输出:

nonce/iv: b17eb886854af06d9d43d4d7
Input Text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer imperdiet pretium leo, et auctor velit fermentum nec. Mauris eu finibus orci. 
Encrypted Hex: facdbb0b024b059d0c78a2634bd6592c04feba0ecb833eee03c7e2c8135854d8ba5bcb80cac1ce8a1c7396fc684e4aa1a44c8b30e9bc800a033ff7ca1a7542a219c42208449232aa671e6443d92c87eca16fb4c06a61d965f455822d8131c26d8bfc6fdfbb5eaae7409516653f33a2c207affdd1539e29e65e236a232b98efc3056e69526115a71837d99f2235d92f6bc64b020e160f44d7281d307ab5cc33791d37bca8423d94f21bf4eccc1717a33891381cb116bbd8dc1f2ae953d94b00f4eef0bc237a7998d99a1a46b9581c34199aeda20cf68158cce43c8492370eccec55dc0f207a495d320aa7d7d8c3bf49c50726046b02ac6e9a9ce6d10d679ff07cff3462bdda051597f0ff5a1f6fb411be3048b72c2d7fe4242783d61d4115a576fcaae05016e6c4648d835b11
decryption matches encrypt
Password Hex:
ce24825df74a15e84597a9446c4821e384661fb790281abec94eab4e5cd95b1b

然后我尝试使用Python 2.7:进行解密

import sys                                                                                          
import binascii                                                                                     
import datetime                                                                                     
import time                                                                                         
from cryptography.hazmat.backends import default_backend                                            
from cryptography.hazmat.primitives.ciphers import (Cipher, algorithms, modes)                      
from Cryptodome.Cipher import AES
hexdata = "facdbb0b024b059d0c78a2634bd6592c04feba0ecb833eee03c7e2c8135854d8ba5bcb80cac1ce8a1c7396fc684e4aa1a44c8b30e9bc800a033ff7ca1a7542a219c42208449232aa671e6443d92c87eca16fb4c06a61d965f455822d8131c26d8bfc6fdfbb5eaae7409516653f33a2c207affdd1539e29e65e236a232b98efc3056e69526115a71837d99f2235d92f6bc64b020e160f44d7281d307ab5cc33791d37bca8423d94f21bf4eccc1717a33891381cb116bbd8dc1f2ae953d94b00f4eef0bc237a7998d99a1a46b9581c34199aeda20cf68158cce43c8492370eccec55dc0f207a495d320aa7d7d8c3bf49c50726046b02ac6e9a9ce6d10d679ff07cff3462bdda051597f0ff5a1f6fb411be3048b72c2d7fe4242783d61d4115a576fcaae05016e6c4648d835b11"                                                                                  
noncehex = "b17eb886854af06d9d43d4d7"                                                               
keyhex = "ce24825df74a15e84597a9446c4821e384661fb790281abec94eab4e5cd95b1b"                         
nonce = binascii.unhexlify(noncehex)                                                                
assert(len(nonce) == 12)                                                                            
key = binascii.unhexlify(keyhex)                                                                    
assert(len(key) == 32)                                                                              
binary = binascii.unhexlify(hexdata)                                                                
cipher = Cipher(algorithms.AES(key), None, backend=default_backend())                                                                                                   
cipher.mode = modes.GCM(nonce)                                                                      
text = cipher.decryptor().update(binary)                                                            
print(text)
decryptor = AES.new(key=key, mode=AES.MODE_GCM, nonce=nonce)                                        
text = decryptor.decrypt(binary)                                                                    
print(text) 

结果非常接近,但使用两种不同的Python解密器有尾随噪声:

%> ./pydecrypt.py 
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer imperdiet pretium leo, et auctor velit fermentum nec. Mauris eu finibus orci.���7P��&���ջq�
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer imperdiet pretium leo, et auctor velit fermentum nec. Mauris eu finibus orci.���7P��&���ջq�

我做错了什么导致最后发出噪音?我是否遗漏了附加到数据中的内容?(iv/noce是12个字符,但额外的噪声是14个字符,而且值似乎不匹配,所以我不认为是这样。(

如本文所述,它是用于验证块的MAC标记。我在上面的示例代码中看到了它,因为我调用的是decrypt,而不是decrypt_and_verify,如那篇文章中所示。

相关内容

  • 没有找到相关文章

最新更新