Python解密JavaScript AES-GCM后的尾随垃圾

时间:2018-11-07 01:49:02

标签: javascript aes python pycrypto

我将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 / nonce是12个字符,但是额外的噪点是14个字符,并且值似乎不匹配,所以我不认为这样。)

1 个答案:

答案 0 :(得分:0)

this post中所述,它是用于验证块的MAC标签。我在上面的示例代码中看到了它,因为我正在调用decrypt而不是该帖子中所示的decrypt_and_verify