2017-01-18 2 views
0

Я пытаюсь расшифровать зашифрованный AES-256 Base64-кодированный data. Эта часть моего JS кода:Неверное количество значительных байтов при расшифровке AES CFB с CryptoJS

var data = "Ic9OcXxn2MnpgFwH4SHkxSY3laYB+kkevevwOPeQjLEeUsAVcHzLdBJZ1liWK5d94I/uNwyzbk+/l6QH/WsU0mzxuXcqBYl4iRIA7UIfchYJTsoaWAnSIjsioFUBAfc8YCODID0HW4AY7nK6Bb0mTP55HxlWstE92w1uJVMmBmJRscrAxySNlAFzVVGxuiiCc3sJimfbMNajXOUeFgvSzw=="; 
 

 
var base64data = CryptoJS.enc.Base64.parse(data); 
 

 
var encrypted = new CryptoJS.lib.WordArray.init(base64data.words.slice(4)); 
 
var iv = new CryptoJS.lib.WordArray.init(base64data.words.slice(0, 4)); 
 
var key = CryptoJS.enc.Utf8.parse("secure%password!secure%password!"); 
 

 
var cipher = CryptoJS.lib.CipherParams.create({ 
 
    ciphertext: encrypted 
 
}); 
 

 
var decrypted = CryptoJS.AES.decrypt(cipher, key, { 
 
    iv: iv, 
 
    mode: CryptoJS.mode.CFB 
 
}); 
 

 
var result = decrypted.toString(CryptoJS.enc.Utf8); 
 
console.log(decrypted.toString(CryptoJS.enc.Utf8)); 
 
// Wrong Output: {"first_name": "Han 
 

 
console.log(decrypted.sigBytes); 
 

 
decrypted.sigBytes = 144 
 

 
console.log(decrypted.toString(CryptoJS.enc.Utf8)); // Correct 
 
// Correct Output: {"first_name": "Hans-J\u00fcrgen", "last_name": "M\u00fcller", "city": "Hamburg", "number": "20a", "zip": "20456", "street": "Ladenstra\u00dfe"}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/mode-cfb.js"></script>

Первый выход из WordBuffer приводит только часть расшифрованных данных, так как значимые байты устанавливаются на 19 вместо 144. После исправления этой , выход неправильный.

Почему я должен исправить руководство sigBytes? Есть идеи? Спасибо!

ответ

0

Я сам нашел ответ. На самом деле проблема не в коде javascript. Это было в коде Python, который зашифровал данные.

При настройке размера сегмента на 128 в pycrpyto с использованием AES CFB вам нужно заполнить свою дату, чтобы склеить ее на кратное 16 байт.

Вот мой полный код шифрования питона, в котором data ссылается на некоторую строку байта и key 32-байтовый ключ шифрования.

length = 16 - (len(data) % 16) 
data += bytes([length]) * length 

iv = Random.new().read(AES.block_size) 
key = options.encrypt_key.encode() 
cipher = AES.new(key, AES.MODE_CFB, iv, segment_size=128) 

crypted = cipher.encrypt(data) 
entry = iv + crypted 
entry = base64.b64encode(entry) 

запись, посылают клиенту, который расшифровывает данные еще раз с помощью следующего кода, в котором data представляет собой кодировку base64 зашифрованные данные из кода питона и key снова одно и то же 32 байт длиной ключа:

var base64data = CryptoJS.enc.Base64.parse(data); 

var encrypted = new CryptoJS.lib.WordArray.init(base64data.words.slice(4)); 
var iv = new CryptoJS.lib.WordArray.init(base64data.words.slice(0, 4)); 

var cipher = CryptoJS.lib.CipherParams.create({ ciphertext: encrypted }); 

var decrypted = CryptoJS.AES.decrypt(cipher, key, {iv: iv, mode: CryptoJS.mode.CFB}); 

Это работает хорошо и в каждом случае.

Смежные вопросы