python3實現AES加密

2021-09-28 21:12:38 字數 4129 閱讀 7511

這幾天研究了一下 python 實現 aes 加密,有很多坑

這個 aes 加密的主要坑就在於這些條件, 首先 aes 加密有一下幾個引數

秘鑰:加密的時候用秘鑰,解密的時候需要同樣的秘鑰才能解出來

明文:需要加密的引數

模式:aes 加密常用的有 ecb 和 cbc 模式(我只用了這兩個模式,還有其他模式)

iv 偏移量:這個引數在 ecb 模式下不需要,在 aes 模式下需要

需要輸入這些引數才能返回乙個密文

下面是重點

下面說一下這幾個引數的條件:

秘鑰:必須是16位位元組或者24位位元組或者32位位元組(因為python3的字串是unicode編碼,需要 encode才可以轉換成位元組型資料)

明文:位元組長度需要是16位的倍數

下面我用python3簡單的方法實現:

from crypto.cipher import aes

import base64

password =

'1234567890123456'

#秘鑰text =

'1234567890123456'

#需要加密的內容

model = aes.mode_ecb #定義模式

aes = aes.new(password,model)

#建立乙個aes物件

en_text = aes.encrypt(text)

#加密明文

print

(en_text)

en_text = base64.encodebytes(en_text)

#將返回的位元組型資料轉進行base64編碼

print

(en_text)

en_text = en_text.decode(

'utf8'

)#將位元組型資料轉換成python中的字串型別

print

(en_text.strip(

))

輸出

b'u|\xcd\x0c\xdc\\\x90\xea\xdb\xee\xec\xf68\xdd\x00\x00'

b'dxzndnxckorb7uz2on0aaa==\n'

dxzndnxckorb7uz2on0aaa==

這裡有個問題就是金鑰和加密的文字內容都必須是固定的16位(根據我前面說的引數要求)

所以下面優化的**(將秘鑰和需要加密的文字補成對應的位數)

from crypto.cipher import aes

import base64

defadd_to_16

(par)

: par = par.encode(

)#先將字串型別資料轉換成位元組型資料

while

len(par)%16

!=0:#對位元組型資料進行長度判斷

par += b'\x00'

#如果位元組型資料長度不是16倍整數就進行 補充

return par

password =

'123456'

#秘鑰text =

'1'#需要加密的內容

model = aes.mode_ecb #定義模式

aes = aes.new(add_to_16(password)

,model)

#建立乙個aes物件

en_text = aes.encrypt(add_to_16(text)

)#加密明文

print

(en_text)

en_text = base64.encodebytes(en_text)

#將返回的位元組型資料轉進行base64編碼

print

(en_text)

en_text = en_text.decode(

'utf8'

)#將位元組型資料轉換成python中的字串型別

print

(en_text.strip(

))

這裡簡單的說一下幾個存在的問題

其實上述**我簡單省略的進行補全到16位,而秘鑰24位也是可以的,你可以自己寫乙個函式來進行秘鑰的補全

為什麼進行補全之前先進行.encode()? 首先encode()不加引數預設是以utf8編碼的,另外先進行encode的原因是因為怕加密的文字中存在漢字,而漢字的utf8編碼的位元組長度是3(gbk對漢字的編碼位元組長度是2),所以為了防止補全的位數不正確,這裡必須先進行轉換(我看到很多別的文章先補全後進行轉換的,而且還是拿空格補全的。。。)

不知道有沒有發現,aes.encrypt()在第乙個程式中我傳遞的是字串型別,第二個程式傳遞的是位元組型資料,這個函式其實是既可以傳遞字串資料型別也可以傳遞位元組型資料的

上面的程式沒有解密函式,所以我對整個加密解密進行了乙個類的最終封裝

from crypto.cipher import aes

import base64

class

aescrypt()

:def

__init__

(self,key,model,iv,encode_)

: self.encode_ = encode_

self.model =

[model]

self.key = self.add_16(key)

if model ==

'ecb'

: self.aes = aes.new(self.key,self.model)

#建立乙個aes物件

elif model ==

'cbc'

: self.aes = aes.new(self.key,self.model,iv)

#建立乙個aes物件

#這裡的金鑰長度必須是16、24或32,目前16位的就夠用了

defadd_16

(self,par)

: par = par.encode(self.encode_)

while

len(par)%16

!=0: par += b'\x00'

return par

defaesencrypt

(self,text)

: text = self.add_16(text)

self.encrypt_text = self.aes.encrypt(text)

return base64.encodebytes(self.encrypt_text)

.decode(

).strip(

)def

aesdecrypt

(self,text)

: text = base64.decodebytes(text.encode(self.encode_)

) self.decrypt_text = self.aes.decrypt(text)

return self.decrypt_text.decode(self.encode_)

.strip(

'\0'

)if __name__ ==

'__main__'

: pr = aescrypt(

'12345'

,'ecb',''

,'gbk'

) en_text = pr.aesencrypt(

'好好學習'

)print

('密文:'

,en_text)

print

('明文:'

,pr.aesdecrypt(en_text)

)

參考:

Python3實現AES加解密

import base64 from crypto.cipher import aes from urllib.parse import unquote 採用aes對稱加密演算法 str不是16的倍數那就補足為16的倍數 def add to 16 value while len value 16 ...

AES對稱加密演算法實踐 python3

下面是在python3中使用mode cbc 需要salt 的最佳實踐 python2環境的見 如果aes加密是mode ecb模式,則不需要隨機向量,中注釋部分 加解密過程 通過 python encode.py 加密本地data目錄下的file.jpg檔案 二進位制 經過加密後生成 data f...

python3實現凱撒加密

愷撒密碼是一種替換加密方式技術。它的加密原理是明文中的所有字母都在字母表上向後 或向前 按照乙個固定數目進行偏移後被替換成密文。根據偏移量的不同,還存在若干特定的愷撒密碼名稱 例如,當偏移量是左移3的時候 解密時的金鑰就是3 明文本母表 abcdefghijklmnopqrstuvwxyz 密文字母...