python 利用Crypto進行AES解密&加密文件

背景:工作需要次和,部分?jǐn)?shù)據(jù)進行了加密傳輸呆盖,對方使用了AES對密碼進行了加密拖云,需要獲取到解密的數(shù)據(jù)。
目標(biāo):通過密鑰成功解密文件应又。
關(guān)鍵詞:AES_ECB宙项,AES_CBC,Java和Python的AES加密問題丁频,

AES加密


一杉允、遇到的問題

收到密鑰&加密文件邑贴,如下席里。需要通過密鑰對信息進行解密。
已知是AES進行的加密數(shù)據(jù)

key = 'Fcniggersm'
message = 'gYknrv3zMWYXEpRLDL0n8q+6s68DKapAfRpBDhN1XGM='

解密測試地址


二拢驾、AES算法簡介

AES算法詳解:高級加密標(biāo)準(zhǔn),它是一種對稱加密算法奖磁,AES只有一個密鑰,這個密鑰既用來加密繁疤,也用于解密咖为。

AES加密方式有五種:ECB, CBC, CTR, CFB, OFB。
從安全性角度推薦CBC加密方法稠腊,本文介紹了CBC,ECB兩種加密方法的python實現(xiàn)躁染。

CBC加密需要一個十六位的key(密鑰)和一個十六位iv(偏移量)
ECB加密不需要iv

接收到的數(shù)據(jù)中只有密鑰而沒有偏移量。故使用ECB處理密文架忌。


三吞彤、準(zhǔn)備工作

python 在 Windows下使用AES時要安裝的是pycryptodome 模塊
python 在 Linux下使用AES時要安裝的是pycrypto模塊

import base64
from Crypto.Cipher import AES
from Crypto import Random
import os
import base64
import json

四、AES-ECB 解密&加密

1、密鑰處理

直接處理密鑰會報錯:‘AES key must be either 16, 24, or 32 bytes long’
因為AES接收的key&vi都必須是有固定長度饰恕。
對Key 進行填充至符合規(guī)格挠羔。

def add_to_16(text):
    while len(text) % 16 != 0:
        text += '\0'
    return (text)

key = 'Fcniggersm'
key = add_to_16(key) 
2、密文處理

有可能處理密文時候會報錯:'Error: Incorrect padding'
這是因為密文長度不符合規(guī)格埋嵌,對base64解碼的string補齊等號就可以了

def decode_base64(data):
    missing_padding = 4-len(data)%4
    if missing_padding:
        data += b'='*missing_padding
    return (data)

message = 'gYknrv3zMWYXEpRLDL0n8q+6s68DKapAfRpBDhN1XGM='
encrypt_data = message 
encrypt_data = decode_base64(encrypt_data)
3破加、解密處理

解密成功獲取到a,再對a進行解碼處理獲取數(shù)據(jù)雹嗦。

cipher = AES.new(key)
result2 = base64.b64decode(encrypt_data)
a = cipher.decrypt(result2)

a = a.decode('utf-8','ignore')
a = a.rstrip('\n')
a = a.rstrip('\t')
a = a.rstrip('\r')
a = a.replace('\x06','')
print('\n','data:',a)

#data: 儒雅隨和范舀,加大力度
4、加密處理

同理可以對字符進行加密處理了罪,執(zhí)行AES加密及解密方法尿背。

 # encoding:utf-8

def encrypt(data, password):
    bs = AES.block_size
    pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
    cipher = AES.new(password)
    data = cipher.encrypt(pad(data))
    return (data)
    
if __name__ == '__main__':
    data = 'ni hao'
    password = 'aesrsasec' #16,24,32位長的密碼
    password = add_to_16(password)        
    encrypt_data = encrypt(data, password)
    encrypt_data = base64.b64encode(encrypt_data)
    print ('encrypt_data:', encrypt_data)

五、AES-CBC 解密&加密

CBC & ECB相比多出了一個vi(偏移量)捶惜。
cipher = AES.new(self.__key, AES.MODE_CBC, iv)
python AES 雙向?qū)ΨQ加密解密

# encoding:utf-8
import base64
from Crypto.Cipher import AES
from Crypto import Random
 
def encrypt(data, password):
    bs = AES.block_size
    pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
    iv = Random.new().read(bs)
    cipher = AES.new(password, AES.MODE_CBC, iv)
    data = cipher.encrypt(pad(data))
    data = iv + data
    return (data)
 
def decrypt(data, password):
    bs = AES.block_size
    if len(data) <= bs:
        return (data)
    unpad = lambda s : s[0:-ord(s[-1])]
    iv = data[:bs]
    cipher = AES.new(password, AES.MODE_CBC, iv)
    data  = unpad(cipher.decrypt(data[bs:]))
    return (data)
 
if __name__ == '__main__':
    data = 'd437814d9185a290af20514d9341b710'
    password = '78f40f2c57eee727a4be179049cecf89' #16,24,32位長的密碼
    encrypt_data = encrypt(data, password)
    encrypt_data = base64.b64encode(encrypt_data)
    print ('encrypt_data:', encrypt_data)
 
 
    encrypt_data = base64.b64decode(encrypt_data)
    decrypt_data = decrypt(encrypt_data, password)
    print ('decrypt_data:', decrypt_data)

六田藐、Java加密&python解密報錯。

實際AES工作中發(fā)現(xiàn)吱七,對方Java加密的文件&自己Python加密的生成的密文不同汽久,導(dǎo)致跨平臺解密錯誤。

可能錯誤的原因:
1踊餐、填充(padding)算法
2景醇、分段大小(segment size)

可參考AES_CFB跨平臺錯誤


7、Linux上解密報錯

在windows上運行無誤吝岭,但是在Lnuix上運行報錯三痰。
①、報錯 new() missing 1 requied positional argument: 'mode'
linux上需要添加窜管,第二參數(shù)散劫,選擇加密模式(本次選擇ECB)

cipher = AES.new(key ,AES.MODE_ECB)

②、報錯 Object type <class 'str'> cannot be passed to C code
linux上傳入的key必須是字節(jié)的形式幕帆,對key 進行處理

key = key.encode('utf-8')
cipher = AES.new(key ,AES.MODE_ECB)

八获搏、小結(jié)

1、處理AES加密時候一定要約定好具體的加密方法失乾。
2常熙、Key,vi 必須是合規(guī)的長度碱茁。
3裸卫、密文也需要做填充處理。
4纽竣、windows ECB自動添加cipher參數(shù)墓贿,且key可以為字符串。linux上需要填寫完整的參數(shù),將key處理成字節(jié)。


九募壕、其他

1调炬、pad和unpad分別是填充函數(shù)和逆填充函數(shù)。因為AES加密對加密文本有長度要求舱馅,必須是密鑰字節(jié)數(shù)的倍數(shù)缰泡。這里的encryptKey在經(jīng)過base64解碼后的長度是16個字節(jié)。
2代嗤、實際上AES加密有AES-128棘钞、AES-192、AES-256三種干毅,分別對應(yīng)三種密鑰長度128bits(16字節(jié))宜猜、192bits(24字節(jié))、256bits(32字節(jié))硝逢。當(dāng)然姨拥,密鑰越長,安全性越高渠鸽,加解密花費時間也越長叫乌。默認(rèn)的是AES-128,其安全性完全夠用徽缚。

填充算法拓展

這里采用的填充算法其實有個專有名詞憨奸,叫pkcs7padding。
簡單解釋就是缺幾位就補幾:填充字符串由一個字節(jié)序列組成凿试,每個字節(jié)填充該填充字節(jié)序列的長度排宰。
如果要填充8個字節(jié),那么填充的字節(jié)的值就是0x08;要填充7個字節(jié),那么填入的值就是0x07那婉;以此類推板甘。
如果文本長度正好是BlockSize長度的倍數(shù),也會填充一個BlockSize長度的值吧恃。這樣的好處是虾啦,根據(jù)最后一個Byte的填充值即可知道填充字節(jié)數(shù)麻诀。

實際上痕寓,java中實現(xiàn)AES加密算法的默認(rèn)模式是Cipher.getInstance("AES/ECB/PKCS5Padding")
PKCS#5在填充方面,是PKCS#7的一個子集:PKCS#5只是對于8字節(jié)(BlockSize=8)進行填充蝇闭,填充內(nèi)容為0x01-0x08呻率;但是PKCS#7不僅僅是對8字節(jié)填充,其BlockSize范圍是1-255字節(jié)呻引。
然而因為AES并沒有64位(8字節(jié))的塊, 如果采用PKCS5, 那么實質(zhì)上就是采用PKCS7礼仗。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子元践,更是在濱河造成了極大的恐慌韭脊,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件单旁,死亡現(xiàn)場離奇詭異沪羔,居然都是意外死亡,警方通過查閱死者的電腦和手機象浑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門蔫饰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人愉豺,你說我怎么就攤上這事篓吁。” “怎么了蚪拦?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵杖剪,是天一觀的道長。 經(jīng)常有香客問我驰贷,道長摘盆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任饱苟,我火速辦了婚禮孩擂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘箱熬。我一直安慰自己类垦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布城须。 她就那樣靜靜地躺著蚤认,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糕伐。 梳的紋絲不亂的頭發(fā)上砰琢,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音良瞧,去河邊找鬼陪汽。 笑死,一個胖子當(dāng)著我的面吹牛褥蚯,可吹牛的內(nèi)容都是我干的挚冤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赞庶,長吁一口氣:“原來是場噩夢啊……” “哼训挡!你這毒婦竟也來了澳骤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤澜薄,失蹤者是張志新(化名)和其女友劉穎为肮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肤京,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡弥锄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蟆沫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片籽暇。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饭庞,靈堂內(nèi)的尸體忽然破棺而出戒悠,到底是詐尸還是另有隱情,我是刑警寧澤舟山,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布绸狐,位于F島的核電站,受9級特大地震影響累盗,放射性物質(zhì)發(fā)生泄漏寒矿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一若债、第九天 我趴在偏房一處隱蔽的房頂上張望符相。 院中可真熱鬧,春花似錦蠢琳、人聲如沸啊终。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蓝牲。三九已至,卻和暖如春泰讽,著一層夾襖步出監(jiān)牢的瞬間例衍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工已卸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留佛玄,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓咬最,卻偏偏與公主長得像翎嫡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子永乌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容