Python 基于pycryptodome,实现对AES、DES、3DES、RSA、blowfish、RC4等常用加密算法的使用,文末附各种加密的源码示例
(中文名:加密圆顶)pycryptodome是一个基于c实现的Python库,它在2.x中支持2.7以上版本,或3.x中支持3.5以上版本的Python。
可以使用以下命令安装它:
pip install pycryptodome
该库支持以下特性
- 认证加密模式 Authenticated encryption modes (GCM, CCM, EAX, SIV, OCB)
- AES加密在英特尔上的加速 Accelerated AES on Intel platforms via AES-NI
- 一种jit编译以提高运算速度 First class support for PyPy
- 椭圆曲线加密 Elliptic curves cryptography (NIST curves P-192, P-224, P-256, P-384 and P-521)
- 更好更紧凑的接口 Better and more compact API (nonce and iv attributes for ciphers, automatic generation of random nonces and IVs, simplified CTR cipher mode, and more)
- 各种hash SHA-3 hash algorithms (FIPS 202) and derived functions (NIST SP-800 185):
- SHAKE128 and SHA256 XOFs
- cSHAKE128 and cSHAKE256 XOFs
- KMAC128 and KMAC256
- TupleHash128 and TupleHash256
- 一个兄弟提出的算法 KangarooTwelve XOF (derived from Keccak)
- SHA散列算法 Truncated hash algorithms SHA-512/224 and SHA-512/256 (FIPS 180-4)
- 一种散列算法 BLAKE2b and BLAKE2s hash algorithms
- 一种流式加密 Salsa20 and ChaCha20/XChaCha20 stream ciphers
- Google所采用的一种新式加密算法 Poly1305 MAC
- 也是Google新算法 ChaCha20-Poly1305 and XChaCha20-Poly1305 authenticated ciphers
- 两种加密算法以及HKDF的推导函数 scrypt, bcrypt and HKDF derivation functions
- DSA加密 Deterministic (EC)DSA
- 密钥保护容器 Password-protected PKCS#8 key containers
- 密钥分享方法 Shamir’s Secret Sharing scheme
- 基于硬件的随机数 Random numbers get sourced directly from the OS (and not from a CSPRNG in userspace)
- 简化的安装流程并且支持windows系统 Simplified install process, including better support for Windows
- RSA和DSA的密钥生成器 Cleaner RSA and DSA key generation (largely based on FIPS 186-4)
- 源码很漂亮 Major clean ups and simplification of the code base
更多文档可参考【官网文档】
概述
DES、3DES、AES都是对称加密算法,即一个密钥既用于加密也用于解密。而RSA是不对称加密,需要使用公钥和私钥分别进行加解密。
对称加密中通常需要三个参数,分别是密钥key
,向量iv
(一种初始的数值用于变更加密的走向以得到不同的加密结果)和密文content
。
不论是DES、3DES,或者还是AES的加密,常用的主要分为MODE_CBC、MODE_CFB、MODE_ECB、MODE_OFB这四种,其他的如EAX等这里不作演示。
四种分组加密模式简介
MODE_ECB
ECB(Electronic Codebook)电码本
- 是一种简单加密
- 这种模式不需要传入
iv
- 但是可能会被明文攻击
- 密钥需要传入8位的bytes
MODE_CBC
(Cipher-block chaining)密码分组链接
- 需要传入8位bytes的
iv
- 密钥需要传入8位的bytes
- 它不容易被主动攻击
- 安全性好于ECB
- 而且就算密文有损坏也还能继续解密
- 适合加密大数据
- 广泛用于SSL、IPSec中。
MODE_CFB
CFB(Cipher FeedBack) 密钥反馈
- 需要传入8位bytes的
iv
- 密钥需要传入8位的bytes
- 密文损坏了会出问题
MODE_OFB
(Output Feedback)输出反馈模式
- 需要传入8位bytes的
iv
- 密钥需要传入8位的bytes
- 密文损坏了会出问题
对称加密
DES加密
from Crypto.Cipher import DES
def padding_to(raw: bytes, padding: int, max_length: int = None):
'''
部分加解密是需要补齐位数到指定padding的
'''
c = len(raw)/padding
block: int = int(c)
if block != c:
block += 1
result = raw.ljust(padding*block, b'\0')
if max_length:
result = result[0:max_length]
return result
def test_des(key,iv,content):
# MODE_CBC
e = DES.new(padding_to(key,8,8), DES.MODE_CBC, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = DES.new(padding_to(key,8,8), DES.MODE_CBC, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_CFB
e = DES.new(padding_to(key,8,8), DES.MODE_CFB, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = DES.new(padding_to(key,8,8), DES.MODE_CFB, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_ECB no need for iv
e = DES.new(padding_to(key,8,8), DES.MODE_ECB).encrypt(padding_to(content,8))
d = DES.new(padding_to(key,8,8), DES.MODE_ECB).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_OFB
e = DES.new(padding_to(key,8,8), DES.MODE_OFB, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = DES.new(padding_to(key,8,8), DES.MODE_OFB, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
config = {
"key": "SGTSerfend2022",
"iv": "1Ssecret1Ssecret1Ssecret"
}
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
iv = str(config['iv']).encode()
key = str(config['key']).encode()
test_des(key,iv,content)
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。
DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
密钥需要是56位(实际使用64位),iv需要是64位
3DES加密
from Crypto.Cipher import DES3
def padding_to(raw: bytes, padding: int, max_length: int = None):
'''
部分加解密是需要补齐位数到指定padding的
'''
c = len(raw)/padding
block: int = int(c)
if block != c:
block += 1
result = raw.ljust(padding*block, b'\0')
if max_length:
result = result[0:max_length]
return result
def test_3des(key,iv,content):
# MODE_CBC
e = DES3.new(padding_to(key,24,24), DES3.MODE_CBC, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = DES3.new(padding_to(key,24,24), DES3.MODE_CBC, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_CFB
e = DES3.new(padding_to(key,24,24), DES3.MODE_CFB, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = DES3.new(padding_to(key,24,24), DES3.MODE_CFB, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_ECB no need for iv
e = DES3.new(padding_to(key,24,24), DES3.MODE_ECB).encrypt(padding_to(content,8))
d = DES3.new(padding_to(key,24,24), DES3.MODE_ECB).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_OFB
e = DES3.new(padding_to(key,24,24), DES3.MODE_OFB, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = DES3.new(padding_to(key,24,24), DES3.MODE_OFB, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
config = {
"key": "SGTSerfend2022",
"iv": "1Ssecret1Ssecret1Ssecret"
}
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
iv = str(config['iv']).encode()
key = str(config['key']).encode()
test_3des(key,iv,content)
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。
由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
密钥需要是3 * 56 = 168位(实际使用192位),iv需要是64位
AES加密
from Crypto.Cipher import AES
def padding_to(raw: bytes, padding: int, max_length: int = None):
'''
部分加解密是需要补齐位数到指定padding的
'''
c = len(raw)/padding
block: int = int(c)
if block != c:
block += 1
result = raw.ljust(padding*block, b'\0')
if max_length:
result = result[0:max_length]
return result
def test_aes(key,iv,content):
# MODE_CBC
e = AES.new(padding_to(key,32,32), AES.MODE_CBC, padding_to(iv,16,16)).encrypt(padding_to(content,16))
d = AES.new(padding_to(key,32,32), AES.MODE_CBC, padding_to(iv,16,16)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_CFB
e = AES.new(padding_to(key,32,32), AES.MODE_CFB, padding_to(iv,16,16)).encrypt(padding_to(content,16))
d = AES.new(padding_to(key,32,32), AES.MODE_CFB, padding_to(iv,16,16)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_ECB no need for iv
e = AES.new(padding_to(key,32,32), AES.MODE_ECB).encrypt(padding_to(content,16))
d = AES.new(padding_to(key,32,32), AES.MODE_ECB).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_OFB
e = AES.new(padding_to(key,32,32), AES.MODE_OFB, padding_to(iv,16,16)).encrypt(padding_to(content,16))
d = AES.new(padding_to(key,32,32), AES.MODE_OFB, padding_to(iv,16,16)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
config = {
"key": "SGTSerfend2022",
"iv": "1Ssecret1Ssecret1Ssecret"
}
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
iv = str(config['iv']).encode()
key = str(config['key']).encode()
test_aes(key,iv,content)
这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 [1] 。
该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael之名命之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 “Rhine doll”。)
密钥需要是32位,iv需要是16位
blowfish加密
from Crypto.Cipher import Blowfish
def padding_to(raw: bytes, padding: int, max_length: int = None):
'''
部分加解密是需要补齐位数到指定padding的
'''
c = len(raw)/padding
block: int = int(c)
if block != c:
block += 1
result = raw.ljust(padding*block, b'\0')
if max_length:
result = result[0:max_length]
return result
def test_Blowfish(key,iv,content):
# MODE_CBC
e = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_CBC, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_CBC, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_CFB
e = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_CFB, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_CFB, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_ECB no need for iv
e = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_ECB).encrypt(padding_to(content,8))
d = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_ECB).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
# MODE_OFB
e = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_OFB, padding_to(iv,8,8)).encrypt(padding_to(content,8))
d = Blowfish.new(padding_to(key,32,32), Blowfish.MODE_OFB, padding_to(iv,8,8)).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
config = {
"key": "SGTSerfend2022",
"iv": "1Ssecret1Ssecret1Ssecret"
}
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
iv = str(config['iv']).encode()
key = str(config['key']).encode()
test_Blowfish(key,iv,content)
Blowfish是一个对称加密块算法,由Bruce Schneider于1993年设计,现已应用在多种加密产品。Blowfish能保证很好的加密速度,并且目前为止没有发现有效地破解方法。目前为止AES比Blowfish有更广的知名度。
密钥需要是32-448位(或1-14个字符),iv需要是8位
RC4加密
from Crypto.Cipher import ARC4
def test_rc4(key: bytes, content: bytes):
e = ARC4.new(key).encrypt(content)
d = ARC4.new(key).decrypt(e)
print(f'e = {e}\nd = {d}\n\n')
assert d == content
if __name__ == '__main__':
config = {
"key": "SGTSerfend2022",
}
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
key = str(config['key']).encode()
test_rc4(key, content)
非对称加密
RSA加密
整体测试示例代码
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
from Crypto.Hash import SHA
def test_rsa(content):
rsa = RSA.generate(2048)
public_key = rsa.public_key().export_key()
private_key = rsa.export_key()
print(f'public_key: {public_key}\n\nprivate_key: {private_key}\n')
private_key = RSA.importKey(private_key)
public_key = RSA.importKey(public_key)
# sign a message
signer = PKCS1_signature.new(private_key)
digest = SHA.new()
digest.update(content)
sign = signer.sign(digest)
print(f'sign: {sign}\n')
# check sign for a message
verifier = PKCS1_signature.new(public_key)
digest = SHA.new()
digest.update(content)
sign_result = verifier.verify(digest,sign)
print(f'the message check sign result is :{sign_result}\n')
# encrypt rsa
cipher = PKCS1_cipher.new(public_key)
encrypt_text = cipher.encrypt(content)
print(f'encrypt_text: {encrypt_text}\n')
# decrypt rsa
cipher = PKCS1_cipher.new(private_key)
decrypt_text = cipher.decrypt(encrypt_text,b'')
print(f'decrypt_text: {decrypt_text}\n')
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
test_rsa(content)
RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的 [1] 。
RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥 [4] 。
产生密钥对
可以是产生128 224 256 512 768 1024 2048等整数位数的密钥
from Crypto.PublicKey import RSA
rsa = RSA.generate(2048)
public_key = rsa.public_key().export_key()
private_key = rsa.export_key()
print(f'public_key: {public_key}\n\nprivate_key: {private_key}\n')
private_key = RSA.importKey(private_key)
public_key = RSA.importKey(public_key)
加解密
利用产生的密钥对,调用
RSA.importKey
分别导入公钥和私钥
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
# sign a message
signer = PKCS1_signature.new(private_key)
digest = SHA.new()
digest.update(content)
sign = signer.sign(digest)
print(f'sign: {sign}\n')
# check sign for a message
verifier = PKCS1_signature.new(public_key)
digest = SHA.new()
digest.update(content)
sign_result = verifier.verify(digest,sign)
print(f'the message check sign result is :{sign_result}\n')
校验签名(判断数据是否是可靠的,没有被篡改的)
使用SHA1等散列算法生成一个hash,用于生成签名
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
content = ('0123456789abcdefAAAAAAAAAA'*5).encode()
# encrypt rsa
cipher = PKCS1_cipher.new(public_key)
encrypt_text = cipher.encrypt(content)
print(f'encrypt_text: {encrypt_text}\n')
# decrypt rsa
cipher = PKCS1_cipher.new(private_key)
decrypt_text = cipher.decrypt(encrypt_text,b'')
print(f'decrypt_text: {decrypt_text}\n')
注意事项
padding_to
方法是因为有些key、iv和待加密的数据的长度是需要是一些数值的倍数,不足长度的是需要补齐的,这里使用\0
对其进行补齐
max_length
是补齐后的最大长度,超过这个长度的数据将会被截取
def padding_to(raw: bytes, padding: int, max_length: int = None):
'''
部分加解密是需要补齐位数到指定padding的
'''
c = len(raw)/padding
block: int = int(c)
if block != c:
block += 1
result = raw.ljust(padding*block, b'\0')
if max_length:
result = result[0:max_length]
return result
其他文档
- CTF逆向-常用的逆向工具 提取码:pnbt
- B站教程中国某省队CTF集训(逆向工程部分)
- 中国某省队CTF集训(逆向工程部分)(已授权)(一)
- 基础加密方式例如
XXTEA
、Base64
换表 - Python库
Z3
方程式、不定式等的约束求解
- 基础的假跳转花指令(脏字节)
- 非自然程序流程
- 扁平化程序控制流
- OLLVM程序流程(虚拟机壳) 很难一般不考
- ida里面按
X
键跟踪,寻找所有Ty
为w
的引用(即类型是写入的),通常就是关键位置
- 中国某省队CTF集训(逆向工程部分)(已授权)(二)
- ollydb动调去壳,upx为例子
- python的逆向和自定义虚拟指令
- 使用pycdc 提取码:dorr 解密python编译的exe或者pyc
- 逐条去解析用py字典手动实现的指令调用
- C++编译的程序的逆向
-
中国某省队CTF集训(逆向工程部分)(已授权)(三)
- 简单模运算加密
- base58 寻找一下特别大的数,这种数通常是算法的标识,或者ida7.7版本以上自带的
find crypt
插件ctrl+alt+f
- 常见的关键位置是有新的内存分配的地方通常是关键地方,或者函数中间突然return的地方也是
- 迷宫题 注意绘制出来就好
- 动调题
- 注意观察会执行的反调试分支,例如出现
int 3
,需要跳过去
- 注意观察会执行的反调试分支,例如出现
- 基本知识
- 大小端序
更多CTF逆向题通用性做法和常用工具下载参考该博文内容:CTF逆向Reverse题的玩法
相关逆向CTF题
-
Python
- Python反汇编方法 Python的pyc字节码反编译反汇编相关知识
- [CTF逆向-羊城杯 2020]Bytecode-WP-Python字节码反编译
-
远程调试汇编
- CTF逆向-[watevrCTF 2019]Timeout-WP-远程调试和修改程序当前运行位置RIP
-
流程控制
- CTF逆向-Dig the way Interesting Pointer-通过栈溢出方式覆盖变量以达到修改执行流程的目的
-
逆向思维
- [CTF逆向-NPUCTF2020]Baby Obfuscation-逆向思维编写脚本以及函数含义的逻辑理解
- [CTF逆向-MRCTF2020]EasyCpp - C++类型的逆向通用操作方法
- [CTF逆向-SUCTF2018]babyre-WP-cpp简单迭代并按表输出值的爆破
-
安卓
- [CTF逆向-网鼎杯 2020 青龙组]bang-安卓脱壳逆向:frida-dexdump导出得到源码
-
虚拟机
- [CTF逆向-GWCTF 2019]babyvm-WP-虚机模拟流程反向编码和z3约束求解器解方程工具的使用
- [CTF逆向-WMCTF2020]easy_re-WP_虚机-perl加载器截取
-
反调试和SMC
- [CTF逆向-SCTF2019]creakme-WP-基于AES加密算法下的保护:反调试及except_handler和SMC
-
加密
- Python 基于pycryptodome,实现对AES、DES、3DES、RSA等常用加密算法的使用,文末附各种加密的源码示例
- [CTF逆向-FlareOn2]very_success-WP_rol循环位移加密
- base64换表
- [CTF逆向-CISCN2018]2ex-WP_mips-32架构以及base64换表
- [CTF逆向-De1CTF2019]Re_Sign-简单脱壳和base64换表编码的深度算法跟踪
-
花指令
- [CTF逆向-SCTF2019]babyre-WP_简单去花指令和流程识别
-
流程混淆的扁平化处理
-
[CTF逆向-RoarCTF2019]polyre-WP_控制流扁平化去混淆idcpy去指令文章来源:https://www.toymoban.com/news/detail-406465.html
-
CTF逆向-[SUCTF2019]hardcpp-使用优化过的deflat.py处理混淆的控制流并将cpp的lambda解析得到实际处理逻辑文章来源地址https://www.toymoban.com/news/detail-406465.html
-
到了这里,关于Python 基于pycryptodome,实现对AES、DES、3DES、RSA等常用加密算法的使用,文末附各种加密的源码示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!