2016-09-23 362 views
1

我在SO上搜索了很多關於完成加密解密示例與我的要求。事實上,我有很多鏈接和例子,但是對於AES-192-CBC模式和AES-256-CBC,我無法使用它。使用PKCS#7填充的Python 3中的AES-CBC 128,192和256加密解密

我得到了下面的例子,它應該與所有類型一起工作,但它只能用於AES-128-CBC模式。我是Python的新手。任何人都可以幫助我,我錯了嗎?

我在Windows上使用Python 3.4,我無法移動到Python 2.7。

import base64 
from Crypto.Cipher import AES 

class AESCipher: 
    class InvalidBlockSizeError(Exception): 
     """Raised for invalid block sizes""" 
     pass 

    def __init__(self, key, block_size=16): 
     if block_size < 2 or block_size > 255: 
      raise AESCipher.InvalidBlockSizeError('The block size must be between 2 and 255, inclusive') 
     self.block_size = block_size 
     self.key = key 
     self.iv = bytes(key[0:16], 'utf-8') 
     print(self.key) 
     print(key[0:16]) 

    def __pad(self, text): 
     text_length = len(text) 
     amount_to_pad = self.block_size - (text_length % self.block_size) 
     if amount_to_pad == 0: 
      amount_to_pad = self.block_size 
     self.pad = chr(amount_to_pad) 
     return text + self.pad * amount_to_pad 

    def __unpad(self, text): 
     #pad = ord(text[-1]) 
     #return text[:-pad] 
     text = text.rstrip(self.pad) 
     return text 

    def encrypt(self, raw): 
     raw = self.__pad(raw) 
     cipher = AES.new(self.key, AES.MODE_CBC, self.iv) 
     return base64.b64encode(cipher.encrypt(raw)) 

    def decrypt(self, enc): 
     enc = base64.b64decode(enc) 
     cipher = AES.new(self.key, AES.MODE_CBC, self.iv) 
     return self.__unpad(cipher.decrypt(enc).decode("utf-8")) 

e = AESCipher('1234567812345678', 16) 
#e = AESCipher('123456781234567812345678', 24) 
#e = AESCipher('12345678123456781234567812345678', 32) 
secret_data = "hi" 
enc_str = e.encrypt(secret_data) 
print('enc_str: ' + enc_str.decode()) 
dec_str = e.decrypt(enc_str) 
print('dec str: ' + dec_str) 

雖然這個代碼加密與192和256位加密的數據,併成功解密太多,但我的其他.Net和Ruby應用程序只能夠解密這是用128加密方法加密的數據。

注意.Net和Ruby應用程序已成功通過相互之間的測試以及使用所有加密類型的聯機加密工具進行測試。

請注意,我的應用程序需要AES-CBC模式和PKCS#7填充,並且必須在Python 3.4上運行。

回答

2

它使用任何加密類型的16個字節的填充工作。爲此,我使用AES.block_size,AES默認爲16。

import base64 
from Crypto.Cipher import AES 

class AESCipher: 
    class InvalidBlockSizeError(Exception): 
     """Raised for invalid block sizes""" 
     pass 

    def __init__(self, key): 
     self.key = key 
     self.iv = bytes(key[0:16], 'utf-8') 
     print(self.key) 
     print(key[0:16]) 

    def __pad(self, text): 
     text_length = len(text) 
     amount_to_pad = AES.block_size - (text_length % AES.block_size) 
     if amount_to_pad == 0: 
      amount_to_pad = AES.block_size 
     pad = chr(amount_to_pad) 
     return text + pad * amount_to_pad 

    def __unpad(self, text): 
     pad = ord(text[-1]) 
     return text[:-pad] 

    def encrypt(self, raw): 
     raw = self.__pad(raw) 
     cipher = AES.new(self.key, AES.MODE_CBC, self.iv) 
     return base64.b64encode(cipher.encrypt(raw)) 

    def decrypt(self, enc): 
     enc = base64.b64decode(enc) 
     cipher = AES.new(self.key, AES.MODE_CBC, self.iv) 
     return self.__unpad(cipher.decrypt(enc).decode("utf-8")) 

e = AESCipher('1234567812345678', 16) 
#e = AESCipher('123456781234567812345678', 24) 
#e = AESCipher('12345678123456781234567812345678', 32) 
secret_data = "hi" 
enc_str = e.encrypt(secret_data) 
print('enc_str: ' + enc_str.decode()) 
dec_str = e.decrypt(enc_str) 
print('dec str: ' + dec_str) 
+0

我不明白這個答案。您已將'self.block_size'更改爲'16',但'block_size'已使用'16'初始化,所以沒有任何更改。你換了別的東西嗎? –

+0

請完整閱讀該問題。我寫過,當我採取24和32塊大小,那麼它不起作用。因爲之前的黑色大小通過參數中傳遞的內容初始化。請參閱__pad函數和註釋代碼man。 –

+0

我明白了。我沒有看到你的評論代碼。儘管如此,AES-256中的256總是意味着密鑰大小而不是塊大小,因爲正如你可能已經知道的那樣,AES有一個16字節的固定塊大小,你可以在pyCrypto中用'AES.block_size'得到這個。您不需要對此進行硬編碼。由於在初始化過程中您不需要傳遞塊大小,因此您應該在答案中包含該代碼(完成後請ping我,以便刪除我的downvote)。 –