2017-01-18 135 views
0

我想解密AES-256加密的Base64編碼的data。我的JS代碼,這部分:使用CryptoJS解密AES CFB時有效字節數量錯誤

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代碼中,它加密了數據。

當使用AES CFB在pycrpyto中將段大小設置爲128時,您必須填寫日期以將其隱藏爲16字節的倍數。

這是我的完整python加密代碼,其中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從Python代碼編碼的加密後的數據和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}); 

這在各種情況下效果良好。