前言:
AES,高級加密標準。目前比較流行的對稱加密算法。是一種對稱加密算法,即加密和解密都用相同的密鑰。
AES只是個基本算法,實現(xiàn)AES有幾種模式,主要有ECB、CBC、CFB等幾種模式。CBC模式中還有一個偏移量參數(shù)IV。
AES加密有AES-128、AES-192和AES-256三種,分別對應三種密鑰長度128位(16字節(jié))、192位(24字節(jié))和256位(32字節(jié))。密鑰越長,安全性越高,加密和解密時間也會更長。一般默認是128位,其安全性完全夠用。
一、加密/解密時,字節(jié)數(shù)不夠時的處理:
加密時:
因為密鑰是16字節(jié),所以明文加密時,字符串不足16字節(jié)的倍數(shù),則要補充個數(shù),例如:少4個,要補chr(4)chr(4)chr(4)chr(4),少2個,要補chr(2)chr(2)。chr(參數(shù))中的參數(shù)是缺少的字節(jié),要補全。這里為什么要補充chr(缺少位的ASCII碼作為參數(shù))。是因為這樣能更好的讀取字符串最后字符時,知道有幾個填充字符,從而能采用字符串切片操作而逆向清除填充字符,為自己理解這點,興奮。
實現(xiàn)方法:明文字符串 + chr(16-len(明文字符串)%16) * (16 - len(明文字符串)%16)?
1、自定義函數(shù)實現(xiàn):
def pad(data):
text = data + chr(16 - len(data) % 16) * (16 - len(data) % 16)
return text
?2、?用lambda匿名函數(shù):(因為只有一個表達式,lambda語法自行查閱)?
pad = lambda s: s + chr(16 - len(s) % 16) * (16 - len(s) % 16)
解密時:
加密時字符串不足16字節(jié)倍數(shù)時,填充的字符是chr(缺少的字節(jié)數(shù)作為參數(shù)的),所以逆向清除填充的字符串,利用最后字符的ASCII碼進行切片得出所需字符串。
1、自定義函數(shù)實現(xiàn):
def unpad(s):
last_num = s[-1]
text = s[:-last_num]
return text
2、?用lambda匿名函數(shù):
unpad = lambda s: s[:-s[-1]]
二、加密、解密用到的庫函數(shù)
Cryptodome和base64庫,聽爬蟲課時,UP說的Crytodo庫安裝出現(xiàn)了問題,查了建議用Cryptodome庫,安裝方法:pip install Cryptodome 安裝正常,base64為內(nèi)置。
base64在這里起什么作用呢?
Base64是網(wǎng)絡上最常見的用于傳輸8Bit字節(jié)碼的編碼方式,能實現(xiàn)二進制與字符之間編碼的互轉(zhuǎn)。所以說Base64就是把字符串以二進制編碼/解碼。其中,b64encode為編碼,b64decode為解碼
三、加密/解密的實現(xiàn)
ECB模式加密:
def aes_ECB_Encrypt(data,key): # ECB模式的加密函數(shù),data為明文,key為16字節(jié)密鑰
key = key.encode('utf-8')
data = pad(data) # 補位
data = data.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_ECB) #創(chuàng)建加密對象
#encrypt AES加密 B64encode為base64轉(zhuǎn)二進制編碼
result = base64.b64encode(aes.encrypt(data))
return str(result,'utf-8') # 以字符串的形式返回
CBC模式加密:
def aes_CBC_Encrypt(data,key,iv): # CBC模式的加密函數(shù),data為明文,key為16字節(jié)密鑰,iv為偏移量
key = key.encode('utf-8')
iv = iv.encode('utf-8') # CBC 模式下的偏移量
data = pad(data) # 補位
data = data.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_CBC,iv=iv) #創(chuàng)建加密對象
#encrypt AES加密 B64encode為base64轉(zhuǎn)二進制編碼
result = base64.b64encode(aes.encrypt(data))
return str(result,'utf-8') # 以字符串的形式返回
解密為逆向:文章來源:http://www.zghlxwxcb.cn/news/detail-414102.html
def aes_ECB_Decrypt(data,key): # ECB模式的解密函數(shù),data為密文,key為16字節(jié)密鑰
key = key.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_ECB) # 創(chuàng)建解密對象
#decrypt AES解密 B64decode為base64 轉(zhuǎn)碼
result = aes.decrypt(base64.b64decode(data))
result = unpad(result) # 除去補16字節(jié)的多余字符
return str(result,'utf-8') # 以字符串的形式返回
def aes_CBC_Decrypt(data,key,iv): # CBC模式的解密函數(shù),data為密文,key為16字節(jié)密鑰
key = key.encode('utf-8')
iv = iv.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_CBC,iv=iv) # 創(chuàng)建解密對象
#decrypt AES解密 B64decode為base64 轉(zhuǎn)碼
result = aes.decrypt(base64.b64decode(data))
result = unpad(result) # 除去補16字節(jié)的多余字符
return str(result,'utf-8') # 以字符串的形式返回
四、附自己做的練習源代碼
import base64
from Crypto.Cipher import AES
str_a = 'This is a book, that is a pen'
pad = lambda s: s + chr(16 - len(s) % 16) * (16 - len(s) % 16)
unpad = lambda s: s[:-s[-1]]
key = 'sdf46asdfs54hgjg'
iv = '0102030405060708'
def aes_ECB_Encrypt(data,key): # ECB模式的加密函數(shù),data為明文,key為16字節(jié)密鑰
key = key.encode('utf-8')
data = pad(data) # 補位
data = data.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_ECB) #創(chuàng)建加密對象
#encrypt AES加密 B64encode為base64轉(zhuǎn)二進制編碼
result = base64.b64encode(aes.encrypt(data))
return str(result,'utf-8') # 以字符串的形式返回
def aes_CBC_Encrypt(data,key,iv): # CBC模式的加密函數(shù),data為明文,key為16字節(jié)密鑰,iv為偏移量
key = key.encode('utf-8')
iv = iv.encode('utf-8') # CBC 模式下的偏移量
data = pad(data) # 補位
data = data.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_CBC,iv=iv) #創(chuàng)建加密對象
#encrypt AES加密 B64encode為base64轉(zhuǎn)二進制編碼
result = base64.b64encode(aes.encrypt(data))
return str(result,'utf-8') # 以字符串的形式返回
def aes_ECB_Decrypt(data,key): # ECB模式的解密函數(shù),data為密文,key為16字節(jié)密鑰
key = key.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_ECB) # 創(chuàng)建解密對象
#decrypt AES解密 B64decode為base64 轉(zhuǎn)碼
result = aes.decrypt(base64.b64decode(data))
result = unpad(result) # 除去補16字節(jié)的多余字符
return str(result,'utf-8') # 以字符串的形式返回
def aes_CBC_Decrypt(data,key,iv): # CBC模式的解密函數(shù),data為密文,key為16字節(jié)密鑰
key = key.encode('utf-8')
iv = iv.encode('utf-8')
aes = AES.new(key=key,mode=AES.MODE_CBC,iv=iv) # 創(chuàng)建解密對象
#decrypt AES解密 B64decode為base64 轉(zhuǎn)碼
result = aes.decrypt(base64.b64decode(data))
result = unpad(result) # 除去補16字節(jié)的多余字符
return str(result,'utf-8') # 以字符串的形式返回
b = aes_ECB_Encrypt(str_a,key)
b1 = aes_ECB_Decrypt(b,key)
c = aes_CBC_Encrypt(str_a,key,iv)
c1 = aes_CBC_Decrypt(c,key,iv)
print("加密前長度:{},加密前字符串為:{}\n加密后長度:{},ECB加密后字符串:{}\n解密后長度:{},解密后字符串:{}\n".format(len(str_a),str_a,len(b),b,len(b1),b1))
print("加密前長度:{},加密前字符串為:{}\n加密后長度:{},CBC加密后字符串:{}\n解密后長度:{},解密后字符串:{}".format(len(str_a),str_a,len(c),c,len(c1),c1))
運行結(jié)果:文章來源地址http://www.zghlxwxcb.cn/news/detail-414102.html
PS D:\python> & "C:/Program Files/Python311/python.exe" d:/python/Crypto_Cipher.py
加密前長度:29,加密前字符串為:This is a book, that is a pen
加密后長度:44,ECB加密后字符串:Y9OEJM1wcv1OwUYmvAEt2cFAPC2Gh1Gk5ts5d+HSngo=
解密后長度:29,解密后字符串:This is a book, that is a pen
加密前長度:29,加密前字符串為:This is a book, that is a pen
加密后長度:44,CBC加密后字符串:FJ7cEn3uKW7aacuC755xkzs4e3T68+bNEVE0SS1emkE=
解密后長度:29,解密后字符串:This is a book, that is a pen
PS D:\python>
到了這里,關(guān)于Python學習筆記——AES 加密/解密的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!