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

背景:工作需要,部分数据进行了加密传输,对方使用了AES对密码进行了加密,需要获取到解密的数据。
目标:通过密钥成功解密文件。
关键词:AES_ECB,AES_CBC,Java和Python的AES加密问题,

AES加密


一、遇到的问题

收到密钥&加密文件,如下。需要通过密钥对信息进行解密。
已知是AES进行的加密数据

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

解密测试地址


二、AES算法简介

AES算法详解:高级加密标准,它是一种对称加密算法,AES只有一个密钥,这个密钥既用来加密,也用于解密。

AES加密方式有五种:ECB, CBC, CTR, CFB, OFB。
从安全性角度推荐CBC加密方法,本文介绍了CBC,ECB两种加密方法的python实现。

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

接收到的数据中只有密钥而没有偏移量。故使用ECB处理密文。


三、准备工作

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 进行填充至符合规格。

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'
这是因为密文长度不符合规格,对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进行解码处理获取数据。

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、加密处理

同理可以对字符进行加密处理,执行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 双向对称加密解密

# 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工作中发现,对方Java加密的文件&自己Python加密的生成的密文不同,导致跨平台解密错误。

可能错误的原因:
1、填充(padding)算法
2、分段大小(segment size)

可参考AES_CFB跨平台错误


7、Linux上解密报错

在windows上运行无误,但是在Lnuix上运行报错。
①、报错 new() missing 1 requied positional argument: 'mode'
linux上需要添加,第二参数,选择加密模式(本次选择ECB)

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

②、报错 Object type <class 'str'> cannot be passed to C code
linux上传入的key必须是字节的形式,对key 进行处理

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

八、小结

1、处理AES加密时候一定要约定好具体的加密方法。
2、Key,vi 必须是合规的长度。
3、密文也需要做填充处理。
4、windows ECB自动添加cipher参数,且key可以为字符串。linux上需要填写完整的参数,将key处理成字节。


九、其他

1、pad和unpad分别是填充函数和逆填充函数。因为AES加密对加密文本有长度要求,必须是密钥字节数的倍数。这里的encryptKey在经过base64解码后的长度是16个字节。
2、实际上AES加密有AES-128、AES-192、AES-256三种,分别对应三种密钥长度128bits(16字节)、192bits(24字节)、256bits(32字节)。当然,密钥越长,安全性越高,加解密花费时间也越长。默认的是AES-128,其安全性完全够用。

填充算法拓展

这里采用的填充算法其实有个专有名词,叫pkcs7padding。
简单解释就是缺几位就补几:填充字符串由一个字节序列组成,每个字节填充该填充字节序列的长度。
如果要填充8个字节,那么填充的字节的值就是0x08;要填充7个字节,那么填入的值就是0x07;以此类推。
如果文本长度正好是BlockSize长度的倍数,也会填充一个BlockSize长度的值。这样的好处是,根据最后一个Byte的填充值即可知道填充字节数。

实际上,java中实现AES加密算法的默认模式是Cipher.getInstance("AES/ECB/PKCS5Padding")
PKCS#5在填充方面,是PKCS#7的一个子集:PKCS#5只是对于8字节(BlockSize=8)进行填充,填充内容为0x01-0x08;但是PKCS#7不仅仅是对8字节填充,其BlockSize范围是1-255字节。
然而因为AES并没有64位(8字节)的块, 如果采用PKCS5, 那么实质上就是采用PKCS7。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容