(中文名:加密圆顶)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
MODE_CBC
(Cipher-block chaining)密码分组链接
iv
MODE_CFB
CFB(Cipher FeedBack) 密钥反馈
iv
MODE_OFB
(Output Feedback)输出反馈模式
iv
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位
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位
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位
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位
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)
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
XXTEA
、Base64
换表Z3
方程式、不定式等的 约束求解
X
键跟踪,寻找所有Ty
为w
的引用(即类型是写入的),通常就是关键位置find crypt
插件ctrl+alt+f
int 3
,需要跳过去更多CTF逆向题通用性做法和常用工具下载参考该博文内容:CTF逆向Reverse题的玩法
Python
远程调试汇编
流程控制
逆向思维
安卓
虚拟机
反调试和SMC
加密
花指令
流程混淆的扁平化处理