版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

常见加解密工具

CyberChef

CyberChef 是一个功能强大的数据处理工具,由 GCHQ(英国政府通信总部)开发。它提供了一系列 加密、解密、编码、解码、数据转换、压缩、哈希、取证分析 等功能,适用于安全研究、数据处理和取证分析等场景。

openssl

OpenSSL 是一个开源加密库,支持 SSL/TLS 协议,实现 RSA、AES、SM2、SM4 等算法,提供加密、证书管理、哈希计算等功能,广泛用于网络安全、身份认证和数据保护。

项目地址:https://github.com/openssl/openssl

各种常见的加密算法在 openssl 中都有实现

word/media/image1.png

cryptopp

Crypto++ 是一个开源 C++ 加密库。

cryptopp 编译相对于 openssl 比较简便,不需要安装特殊依赖环境。

项目地址:https://github.com/weidai11/cryptopp

chilkat

Chilkat 是一个跨平台加密和网络通信库,收费,不开源,但是已经编译好各种平台的库,直接拿来就用。

下载地址:https://www.chilkatsoft.com/downloads.asp

word/media/image2.png

编码算法

编码算法是一种用于数据转换的方法,它将信息从一种格式转换为另一种格式,便于存储和传输。

Hex

Hex 编码是一种将二进制数据转换为十六进制字符串的编码方式

word/media/image3.png

data = b"Hello"
hex_encoded = data.hex()
print("Hex 编码:", hex_encoded)

hex_decoded = bytes.fromhex(hex_encoded)
print("Hex 解码:", hex_decoded.decode())

输出如下:

Hex 编码: 48656c6c6f
Hex 解码: Hello

URL Encode / URL Decode

URL 编码 是一种用于在 URL 中安全传输特殊字符的编码方式,将非 ASCII 字符、特殊字符转换为百分号(%)+ 两位十六进制数的格式。

URL 解码 是将 URL 编码的内容转换回原始字符的过程。

word/media/image4.png

import urllib.parse

# 原始字符串
text = "Hello World! 你好?"

# URL 编码
encoded_text = urllib.parse.quote(text)
print("URL 编码:", encoded_text)

# URL 解码
decoded_text = urllib.parse.unquote(encoded_text)
print("URL 解码:", decoded_text)

输出如下:

URL 编码: Hello%20World%21%20%E4%BD%A0%E5%A5%BD%EF%BC%9F
URL 解码: Hello World! 你好?

HTML Entity

HTML Entity(HTML 实体编码) 是 HTML 中用于表示特殊字符的编码方式,通常用于防止 HTML 解析错误、显示特殊符号、避免 XSS 攻击(避免 alert(1) 被浏览器解析执行)。

常见 HTML 实体

word/media/image5.png

word/media/image6.png

import html

# HTML 实体编码
text = '<Hello & "World">'
encoded_text = html.escape(text)
print("HTML 实体编码:", encoded_text)

# HTML 实体解码
decoded_text = html.unescape(encoded_text)
print("HTML 实体解码:", decoded_text)

输出如下:

HTML 实体编码: &lt;Hello &amp; &quot;World&quot;&gt;
HTML 实体解码: <Hello & "World">

Base64

Base64 是一种二进制到文本的编码方式,常用于数据传输、存储、避免特殊字符问题。

它将任意二进制数据转换成可打印的 ASCII 字符(A-Z, a-z, 0-9, +, /,=)。

关于 Base64 算法详细介绍:https://zh.wikipedia.org/zh-hans/Base64

标准 Base64 算法中,3个字节为一组由4个可打印字符来表示

word/media/image7.png

不足 3 字节时,用 = 进行填充(占位)。

word/media/image8.png

默认是标准索引表,点右边小三角也可以切换其他变形的索引表

word/media/image9.png 当遇到这种情况就需要从代码中查找对应的索引表了

import base64

# 原始数据
data = "Hello, Base64!"

# Base64 编码
encoded = base64.b64encode(data.encode()).decode()
print("Base64 编码:", encoded)

# Base64 解码
decoded = base64.b64decode(encoded).decode()
print("Base64 解码:", decoded)

输出如下:

Base64 编码: SGVsbG8sIEJhc2U2NCE=
Base64 解码: Hello, Base64!

Hash 算法

Hash 算法(散列算法) 是一种将任意长度的输入数据转换为固定长度的哈希值(摘要)的算法。它不可逆,常用于数据完整性校验、密码存储、数字签名、区块链等。

CRC-32

CRC-32 通过 对数据块进行循环冗余校验,生成一个 32位(4字节)的哈希值(通常称为 CRC 校验码),用于验证数据是否在传输过程中发生了变化。

CRC-32 生成 4 个字节 32位 的校验值,554b4ff1 实际上是 Hex,CyberChef 显示的是 Hex 的字符串

word/media/image10.png

word/media/image11.png

import binascii

# 数据
data = b"Hello, CRC-32!"

# 计算 CRC-32
crc32_value = binascii.crc32(data)
print(f"CRC-32 校验值: {crc32_value:#010x}")

输出如下:

CRC-32 校验值: 0x84d41ca3

MD5

MD5 是一种广泛使用的哈希函数,旨在生成一个128位(16字节)的哈希值,通常以32位十六进制数表示。它最初由 Ronald Rivest 在 1991 年设计,用于数据完整性校验,例如文件校验、数字签名等应用。

特征:固定返回长度为 32 位的字符串

word/media/image12.png

Hex 数据

word/media/image13.png

To Hexdump 可以看到数据在内存中的分布就是这样

word/media/image14.png

import hashlib

# 数据
data = "Hello, MD5!"

# 计算 MD5
md5_hash = hashlib.md5(data.encode()).hexdigest()
print(f"MD5 哈希值: {md5_hash}")

输出如下:

MD5 哈希值: 383e139e64e5f46de9d03ba3695da2d8

SHA1

SHA-1 是由美国国家安全局(NSA)设计的一种哈希函数,它生成一个160位的哈希值(通常表示为 40 位的十六进制数)。SHA-1 最初是作为 SHA 系列的一部分,在 数据完整性校验、数字签名等领域被广泛使用。

特征:

  • 固定返回长度为 40 位的字符串

  • 只有字母和数字,没有特殊符号

word/media/image15.png

import hashlib

# 数据
data = "Hello, SHA-1!"

# 计算 SHA-1
sha1_hash = hashlib.sha1(data.encode()).hexdigest()
print(f"SHA-1 哈希值: {sha1_hash}")

输出如下:

SHA-1 哈希值: f322e078fef4f49da1618d3793d3272a91f0488c

SHA256

SHA-256 是 SHA-2(Secure Hash Algorithm 2)系列中的一种哈希函数,它生成一个 256位的哈希值(通常表示为 64 位的十六进制数)。SHA-256 是现代加密和数据完整性校验中广泛使用的算法,具有较高的安全性。

特征:

  • 固定返回长度为 64 位的字符串

  • 只有字母和数字,没有特殊符号

word/media/image16.png

import hashlib

# 数据
data = "Hello, SHA-256!"

# 计算 SHA-256
sha256_hash = hashlib.sha256(data.encode()).hexdigest()
print(f"SHA-256 哈希值: {sha256_hash}")

输出如下:

SHA-256 哈希值: d0e8b8f11c98f369016eb2ed3c541e1f01382f9d5b3104c9ffd06b6175a46271

HMAC

HMAC(基于哈希的消息认证码)使用一个密钥(Key)和一个哈希函数(Hash Function),将输入消息进行加密计算,生成一个固定长度的认证码(MAC)。它结合了哈希函数和密钥,提供了一种 安全的哈希过程,防止消息在传输过程中被篡改或伪造。

比如哈希函数是 MD2,密钥可能有也可能没有

word/media/image17.png

当哈希函数是 MD5 ,密钥是 cyrus

word/media/image18.png

所以返回字符串长度取决于具体的哈希函数

word/media/image19.png

import hmac
import hashlib

# 密钥和数据
key = b"secret_key"
message = b"Hello, HMAC!"

# 计算 HMAC-SHA256
hmac_result = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f"HMAC 哈希值: {hmac_result}")

输出如下:

HMAC 哈希值: e27642cd349f85fa9b8ed8309230cf19c24d4780db1f5d4b3012ad994930f072

Adler-32

Adler-32 是一个 32位(4字节) 的哈希算法,它通过计算数据的部分和和累积值来生成一个 32 位的校验和。

它由 Mark Adler 于 1995 年提出,主要用于检测数据完整性。虽然它不如 CRC-32 或 SHA-256 那样强大,但由于其计算速度快,广泛用于 压缩格式(如 zlib)中。

特征和 CRC-32 差不多

word/media/image20.png

import zlib

# 数据
data = b"Hello, Adler-32!"

# 计算 Adler-32 校验和
adler32_hash = zlib.adler32(data)  # 保证输出为 32 位
print(f"Adler-32 校验和: {adler32_hash:#010x}")

输出如下:

Adler-32 校验和: 0x2cfe04dc

对称算法

对称算法是一种加密算法,使用相同的密钥进行加密和解密。这种方式的优点是加密和解密速度非常快,但问题在于密钥的传输和管理上,因为如果密钥被泄露,加密信息也会暴露。

XOR

最简单的对称加密:异或(相同为 0,不同为 1)。

word/media/image21.png

def xor_encrypt_decrypt(data, key):
    return bytes([b ^ key for b in data])

# 原始数据
plaintext = b"Hello"

# 密钥(单字节)
key = 42  # 任何数都可以作为密钥

# 加密
ciphertext = xor_encrypt_decrypt(plaintext, key)
print("密文:", ciphertext)

# 解密
decrypted = xor_encrypt_decrypt(ciphertext, key)
print("解密:", decrypted.decode())

输出如下:

密文: b'bOFFE'
解密: Hello

RC4

RC4(Rivest Cipher 4)是一种流加密算法,由 Ronald Rivest 于 1987 年 设计,最初是 RSA Security 的专有算法,后被泄露并公开。

RC4 运算速度快、实现简单,曾被广泛用于SSL/TLS、WEP、VPN、无线网络安全等,但由于安全漏洞,目前已被淘汰。

使用 RC4 算法和密钥 cyrus 计算加密数据

word/media/image22.png

把加密后的数据使用密码 cyrus 和 RC4 算法再计算一次得到未加密的数据

word/media/image23.png

RC4 依赖 XOR 进行加解密,因此加密和解密过程完全相同。

def rc4(data: bytes, key: bytes) -> bytes:
    S = list(range(256))  # S 盒初始化
    j = 0
    out = bytearray()

    # KSA(密钥调度算法)
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]  # 交换

    # PRGA(伪随机生成)
    i = j = 0
    for byte in data:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]  # 交换
        k = S[(S[i] + S[j]) % 256]
        out.append(byte ^ k)  # XOR 计算密文

    return bytes(out)

# 测试 RC4 加密和解密
key = b"SecretKey"
plaintext = b"Hello, RC4!"

ciphertext = rc4(plaintext, key)
print("密文:", ciphertext)

decrypted = rc4(ciphertext, key)  # 再次 RC4 处理即可解密
print("解密:", decrypted.decode())

输出如下:

密文: b"\\\xddP+\xb0^>\xf0\xa7'\x1c"
解密: Hello, RC4!

DES

DES 是一种 分组加密算法,采用 64 位数据块,并使用 56 位密钥(64 位密钥中 8 位是奇偶校验位)。

1. Key(密钥)

  • 密钥长度:64 位(8 字节)

  • 但其中 56 位 是有效密钥位,剩余的 8 位 用作奇偶校验。

2. IV(初始化向量)

初始化向量(IV)是用于某些加密模式(如 CBC、CFB、OFB)的 随机数,用于增加加密的随机性,防止相同明文产生相同密文。

  • IV 必须与数据块大小相同,即 8 字节(64 位)。

  • ECB 模式不需要 IV,但 CBC、CFB、OFB 模式需要 IV。

3. Mode(加密模式)

Mode 中 CBC 和 ECB 是比较常见的

CBC 每个块会依赖前一个块,ECB 每个块单独加密

Key 和 IV 必须为 8 个字节

word/media/image24.png

Python 的 pycryptodome 库提供了 DES 实现:

pip install pycryptodome

ECB(电子密码本模式,Electronic Codebook)

  • 特点:

  • 每个 8 字节的明文独立加密,相同的明文块总是会产生相同的密文。

  • 不需要 IV。

  • 适用场景:仅适用于单独的数据块,不适用于长数据。

word/media/image25.png

Python 代码示例

from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad

key = b'8ByteKey'  # 8 字节密钥(56 位有效)
data = b"Hello, DES!"  # 待加密数据

# 创建 DES 加密器(ECB 模式)
cipher = DES.new(key, DES.MODE_ECB)

# 加密
ciphertext = cipher.encrypt(pad(data, DES.block_size))
print("密文:", ciphertext.hex())

# 解密
plaintext = unpad(cipher.decrypt(ciphertext), DES.block_size)
print("解密:", plaintext.decode())

输出如下:

密文: 583d732b24aa664ec46b788d096a2da5
解密: Hello, DES!

CBC(密码分组链接模式,Cipher Block Chaining)

  • 特点

  • 每个明文块 在加密前与前一个密文块 XOR,这样相同的明文块不会产生相同的密文。

  • 需要 IV(初始化向量)。

  • 适用场景:适用于大多数加密需求,如 文件、网络通信等。

word/media/image26.png

Python 代码示例

from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad

# 设置密钥(8 字节)和 IV(8 字节)
key = b'8ByteKey'
iv = b'12345678'

# 明文
data = b"Hello, DES!"

# 创建加密对象
cipher_encrypt = DES.new(key, DES.MODE_CBC, iv)

# 加密
ciphertext = cipher_encrypt.encrypt(pad(data, DES.block_size))
print("CBC 密文:", ciphertext.hex())

# 创建解密对象( PyCryptodome 不允许在同一个 Cipher 对象上既加密又解密。)
cipher_decrypt = DES.new(key, DES.MODE_CBC, iv)

# 解密
plaintext = unpad(cipher_decrypt.decrypt(ciphertext), DES.block_size)
print("CBC 解密:", plaintext.decode())

输出如下:

CBC 密文: 4c5d97b0607bd66e3c35a54a92f058ea
CBC 解密: Hello, DES!

CFB(密码反馈模式,Cipher Feedback)

  • 特点:

  • 类似于 CBC,但它以流模式工作,加密块可以小于 8 字节。

  • 需要 IV。

  • 适用场景:适用于 需要流加密的应用。

Python 代码示例

from Crypto.Cipher import DES

# 设置密钥(8 字节)和 IV(8 字节)
key = b'8ByteKey'
iv = b'12345678'

# 明文
data = b"Hello, DES!"

# 创建加密对象
cipher_encrypt = DES.new(key, DES.MODE_CFB, iv)

# 加密
ciphertext = cipher_encrypt.encrypt(data)
print("CFB 密文:", ciphertext.hex())

# 创建解密对象( PyCryptodome 不允许在同一个 Cipher 对象上既加密又解密。)
cipher_decrypt = DES.new(key, DES.MODE_CFB, iv)

# 解密
plaintext = cipher_decrypt.decrypt(ciphertext)
print("CFB 解密:", plaintext.decode())

OFB(输出反馈模式,Output Feedback)

  • 特点:

  • 以流模式工作,不会传播加密错误。

  • 需要 IV。

  • 适用于实时加密(如语音、视频加密)。

Python 代码示例

from Crypto.Cipher import DES

# 设置密钥(8 字节)和 IV(8 字节)
key = b'8ByteKey'
iv = b'12345678'

# 明文
data = b"Hello, DES!"

# 创建加密对象
cipher_encrypt = DES.new(key, DES.MODE_OFB, iv)

# 加密
ciphertext = cipher_encrypt.encrypt(data)
print("OFB 密文:", ciphertext.hex())

# 创建解密对象( PyCryptodome 不允许在同一个 Cipher 对象上既加密又解密。)
cipher_decrypt = DES.new(key, DES.MODE_OFB, iv)

# 解密
plaintext = cipher_decrypt.decrypt(ciphertext)
print("OFB 解密:", plaintext.decode())

输出如下:

OFB 密文: ca5578137e3d02503a6f02
OFB 解密: Hello, DES!

CTR(计数器模式,Counter Mode)

  • 特点:

  • 将 IV 作为 计数器,不断递增,生成独立的加密流。

  • 适用于 并行计算,效率高。

  • 适用场景:适用于 高性能并行加密。

Python 代码示例

from Crypto.Cipher import DES
from Crypto.Util import Counter

# 设置密钥(8 字节)
key = b'8ByteKey'

# 计数器(CTR 模式不需要 IV,而是用 Counter)
ctr = Counter.new(64)

# 创建加密对象
cipher_encrypt = DES.new(key, DES.MODE_CTR, counter=ctr)

# 明文
data = b"Hello, DES!"

# 加密
ciphertext = cipher_encrypt.encrypt(data)
print("CTR 密文:", ciphertext.hex())

# **重新创建 Counter,确保加密和解密使用相同的计数器初始值**
ctr = Counter.new(64)  # 重新创建计数器,保证与加密时一致

# 创建解密对象
cipher_decrypt = DES.new(key, DES.MODE_CTR, counter=ctr)

# 解密
plaintext = cipher_decrypt.decrypt(ciphertext)
print("CTR 解密:", plaintext.decode())

输出如下:

CTR 密文: fe79bfdfe81bf8306254a8
CTR 解密: Hello, DES!

DES 各模式对比

模式是否需要 IV加密方式特点适用场景
ECB不需要每个块独立加密易被模式分析,不安全仅适用于少量数据
CBC需要 IVXOR 前一块密文更安全,适用于文件加密文件、数据库
CFB需要 IV流式加密适用于流数据网络通信
OFB需要 IV流式加密(错误不会传播)适用于实时加密语音、视频
CTR需要计数器伪随机数流可并行计算,速度快高性能并行加密

3DES(Triple DES)

3DES(Triple Data Encryption Standard,三重数据加密标准) 是 DES(数据加密标准) 的加强版,通过对数据进行 三次加密 提高安全性

Key 16 或 24 字节,IV 8 个字节

word/media/image27.png

from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad, unpad

# 3DES 密钥(必须是 16 或 24 字节)
key = b'Sixteen byte key'  # 16 字节密钥
iv = b'12345678'  # 8 字节 IV

# 创建 3DES CBC 加密对象
cipher_encrypt = DES3.new(key, DES3.MODE_CBC, iv)

# 明文
data = b"Hello, 3DES!"

# 加密
ciphertext = cipher_encrypt.encrypt(pad(data, DES3.block_size))
print("3DES 密文:", ciphertext.hex())

# 解密(重新创建对象)
cipher_decrypt = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = unpad(cipher_decrypt.decrypt(ciphertext), DES3.block_size)
print("3DES 解密:", plaintext.decode())

输出如下:

3DES 密文: c83780a4aa2a69e83694b085690f6d23
3DES 解密: Hello, 3DES!

AES

AES(Advanced Encryption Standard,高级加密标准) 是一种 对称加密算法,用于加密和解密数据。AES 由 美国国家标准与技术研究院(NIST) 在 2001 年正式发布,取代了 DES 和 3DES,目前被广泛应用于 网络安全、金融、通信 等领域。

支持 128(16字节)、192(24字节)、256(32字节) 位密钥。

word/media/image28.png

特性描述
加密方式对称加密(加密和解密使用相同的密钥)
分组长度128 位(16 字节)
密钥长度128 位、192 位、256 位(分别对应 10、12、14 轮加密)
安全性目前无已知有效攻击,比 3DES 更安全
运算模式支持 ECB、CBC、CFB、OFB、CTR 等模式
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

# 16 字节(128 位)密钥
key = b'Sixteen byte key'
iv = b'1234567890123456'  # 16 字节 IV(仅 CBC 需要)

# 创建 AES CBC 加密对象
cipher_encrypt = AES.new(key, AES.MODE_CBC, iv)

# 明文(需填充到 16 字节倍数)
data = b"Hello, AES!"
ciphertext = cipher_encrypt.encrypt(pad(data, AES.block_size))
print("AES CBC 密文:", ciphertext.hex())

# 解密
cipher_decrypt = AES.new(key, AES.MODE_CBC, iv)
plaintext = unpad(cipher_decrypt.decrypt(ciphertext), AES.block_size)
print("AES CBC 解密:", plaintext.decode())

输出如下:

AES CBC 密文: 03f4e378d5f8be3ecf2294490dd5bfff
AES CBC 解密: Hello, AES!

国密 SM4

GmSSL,支持国密算法(SM2/SM3/SM4)的开源 SSL/TLS 加密库 :http://gmssl.org/docs/sm4.html

算法文档:GM/T0002-2012《SM4分组密码算法》

SMS4的密钥长度和分组长度均为128比特,其设计安全性等同于AES-128,但是近年来的一些密码分析表明SMS4的安全性略弱于AES-128。

在国内一些 zf 和银行 app 用的比较多。

word/media/image29.png

特性描述
算法类型对称加密(加密解密使用相同密钥)
分组大小128 位(16 字节)
密钥长度128 位(16 字节)
加密轮数32 轮
安全性比 DES/3DES 更安全,可替代 AES-128
运算模式支持 ECB、CBC、CFB、OFB、CTR
pip install gmssl
from gmssl import sm4
from Crypto.Util.Padding import pad, unpad

# 16 字节密钥(128 位)
key = b'1234567890abcdef'
iv = b'1234567890abcdef'  # 仅 CBC 需要

# 创建 SM4 CBC 加密对象
cipher_encrypt = sm4.CryptSM4()
cipher_encrypt.set_key(key, sm4.SM4_ENCRYPT)

# 明文
data = b"Hello, SM4!"
ciphertext = cipher_encrypt.crypt_cbc(iv, pad(data, 16))
print("SM4 CBC 密文:", ciphertext.hex())

# 解密
cipher_decrypt = sm4.CryptSM4()
cipher_decrypt.set_key(key, sm4.SM4_DECRYPT)
plaintext = unpad(cipher_decrypt.crypt_cbc(iv, ciphertext), 16)
print("SM4 CBC 解密:", plaintext.decode())

输出如下:

SM4 CBC 密文: 67cb1b462378a51d8bd04fcd9e2094157bb51f24808a845f07ed14f5ec6f0575
SM4 CBC 解密: Hello, SM4!

非对称算法

非对称算法(Asymmetric Algorithm) 是一种使用不同的密钥进行加密和解密的加密算法,包括公钥(Public Key)和私钥(Private Key)。

  • 公钥加密,私钥解密(用于安全通信)

  • 私钥加密,公钥验证(用于数字签名)

非对称算法的特点

  • 密钥对(公钥 + 私钥):无需共享私钥,避免密钥分发问题。

  • 支持数字签名:可验证数据来源和完整性,防止篡改。

  • 比对称加密慢:计算复杂,通常用于密钥交换和身份认证,大数据加密仍用对称算法(如 AES)。

RSA

RSA(Rivest-Shamir-Adleman) 是一种 非对称加密算法,1977 年由 Ron Rivest、Adi Shamir 和 Leonard Adleman 提出。它基于 大整数因子分解问题 的数学难题,广泛用于 数据加密、数字签名、密钥交换 等领域。

详细介绍:RSA加密算法

生成私钥和公钥

RSA Key Generator:https://emn178.github.io/online-tools/rsa/key-generator/

word/media/image30.png

常见密钥长度

密钥长度安全性应用场景
512 位极不安全早已被破解,不推荐使用
1024 位不安全2003 年 NIST 就不推荐
2048 位目前安全最低推荐,适用于一般应用
3072 位更安全适用于高安全需求,如数字签名
4096 位极高安全性适用于 长期数据保护
8192+ 位超高安全性计算开销巨大,极少使用

使用公钥加密数据

RSA Encrypt:https://emn178.github.io/online-tools/rsa/encrypt/

word/media/image31.png

使用私钥解密数据

RSA Decrypt:https://emn178.github.io/online-tools/rsa/decrypt/

word/media/image32.png

生成 RSA 密钥

from Crypto.PublicKey import RSA

# 生成 2048 位密钥对
key = RSA.generate(2048)

# 导出公钥 & 私钥
private_key = key.export_key()
public_key = key.publickey().export_key()

# 保存到文件
with open("rsa_private.pem", "wb") as f:
    f.write(private_key)
with open("rsa_public.pem", "wb") as f:
    f.write(public_key)

print("RSA 密钥对已生成")

RSA 加密

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
import base64

# 加载公钥
with open("rsa_public.pem", "rb") as f:
    public_key = RSA.import_key(f.read())

# 创建加密器
cipher = PKCS1_OAEP.new(public_key)

# 加密
plaintext = "Hello, RSA!"
ciphertext = cipher.encrypt(plaintext.encode())

# 转 Base64 输出
print("密文:", base64.b64encode(ciphertext).decode())

输出如下:

密文: MvznGTUHQ9SJ2IqXZ6jGQL0Mu2oWDa0kSWJRB2+8aSvzTl9MWc7qaTk816y1po4DsA3o0mkr6k1jon/qglNevPU21FqE+P2EFA3AT/1pciztZrWdiy8lbQ0RkqQOb9lZ4TcuvAR28Be9KtDgJJSc3Gfi2wCd1lvE+hfyQnHYLPDm2Vl8eulCIPz/awCe7T+aFeRXAUAZNbIk2y7jOP8CSn/m8jLgwOQ7rr73SKyKzgCD5qxzBJqNwNe7L3uLXSCMqB+2hheJram7cVdPDVXljQ86spQxrcyfc4bKgKEcIxs0uR3XjamLnHhfuTgEDcqLKCgwdwPahJq13SMlkQrjuw==

RSA 与 AES 结合使用

RSA 与 AES 结合使用的方法

  • 用 AES 加密数据(对称加密,速度快)。

  • 用 RSA 加密 AES 密钥(非对称加密,确保密钥安全)。

  • 发送加密的 AES 密钥 + 加密数据,接收方用 RSA 解密 AES 密钥,再用 AES 解密数据。

结合两者优点,既安全又高效,是 TLS/HTTPS、文件加密、数据传输 的常用方案。

发送方:AES 加密数据 & RSA 加密 AES 密钥

from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
import base64

# 读取 RSA 公钥
with open("rsa_public.pem", "rb") as f:
    public_key = RSA.import_key(f.read())

# 生成 AES 密钥(16/24/32 字节,对应 AES-128/192/256)
aes_key = get_random_bytes(16)  # 这里使用 AES-128

# 创建 AES 加密器(CBC 模式)
iv = get_random_bytes(16)  # IV 向量
cipher_aes = AES.new(aes_key, AES.MODE_CBC, iv)

# 加密数据
plaintext = b"Hello, RSA + AES!"
padded_plaintext = plaintext + b' ' * (16 - len(plaintext) % 16)  # 填充
ciphertext = cipher_aes.encrypt(padded_plaintext)

# 用 RSA 公钥加密 AES 密钥
cipher_rsa = PKCS1_OAEP.new(public_key)
encrypted_aes_key = cipher_rsa.encrypt(aes_key)

# 发送以下数据:
# 1. `encrypted_aes_key`(RSA 加密后的 AES 密钥)
# 2. `iv`(AES IV)
# 3. `ciphertext`(AES 加密后的数据)
print("RSA 加密后的 AES 密钥:", base64.b64encode(encrypted_aes_key).decode())
print("AES IV:", base64.b64encode(iv).decode())
print("AES 加密后的数据:", base64.b64encode(ciphertext).decode())

输出如下:

RSA 加密后的 AES 密钥: HX9pSwziu9Sz0bqBMSVroFPDqQCDoh6o1q/VH9UmfcRU2eMjlgyKJy2WUiXe2YqnRSILE8kJ9SVa8sZgdtWoyVyvLK49AUGjlm7LDEsYPX7uXo2y9yn9kUoQc9WXdsiOBcshG0hsXwNssOtRL7jWfH5lYDcKrP9i1wYcvQiGw61tGM4zR9A0ao0Qi5ajGmyMfLAGpodFuUvSA1ocXoWZG31zG0YgY5tjPNQXf1EbXjVk0aStwyHjVUu6svN8li9AHzOWF42HjCPCyCAHvbicFTFhxHdK3zORqhcAv7avybDugwxAMTskSfhHoHZ2k+Lac08se9fFMs5wd6JbtgBpCQ==
AES IV: fEYV2sUEJxoEfyabNxJl8g==
AES 加密后的数据: 8zUQ/tExI1+vk/BAOmn67hV4tTNLVnurhgN/RkG9cNU=

接收方:RSA 解密 AES 密钥 & AES 解密数据

from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA
import base64

# 读取 RSA 私钥
with open("rsa_private.pem", "rb") as f:
    private_key = RSA.import_key(f.read())

# 接收的加密数据
encrypted_aes_key = base64.b64decode("HX9pSwziu9Sz0bqBMSVroFPDqQCDoh6o1q/VH9UmfcRU2eMjlgyKJy2WUiXe2YqnRSILE8kJ9SVa8sZgdtWoyVyvLK49AUGjlm7LDEsYPX7uXo2y9yn9kUoQc9WXdsiOBcshG0hsXwNssOtRL7jWfH5lYDcKrP9i1wYcvQiGw61tGM4zR9A0ao0Qi5ajGmyMfLAGpodFuUvSA1ocXoWZG31zG0YgY5tjPNQXf1EbXjVk0aStwyHjVUu6svN8li9AHzOWF42HjCPCyCAHvbicFTFhxHdK3zORqhcAv7avybDugwxAMTskSfhHoHZ2k+Lac08se9fFMs5wd6JbtgBpCQ==")
iv = base64.b64decode("fEYV2sUEJxoEfyabNxJl8g==")
ciphertext = base64.b64decode("8zUQ/tExI1+vk/BAOmn67hV4tTNLVnurhgN/RkG9cNU=")

# 用 RSA 私钥解密 AES 密钥
cipher_rsa = PKCS1_OAEP.new(private_key)
aes_key = cipher_rsa.decrypt(encrypted_aes_key)

# 用 AES 密钥解密数据
cipher_aes = AES.new(aes_key, AES.MODE_CBC, iv)
plaintext = cipher_aes.decrypt(ciphertext)

print("解密后的数据:", plaintext.decode())

输出如下:

解密后的数据: Hello, RSA + AES!

ECC

ECC(Elliptic Curve Cryptography,椭圆曲线密码学)是一种 非对称加密算法,基于 椭圆曲线离散对数问题(ECDLP),提供与 RSA 相同安全级别,但密钥更短、计算更快、资源占用更少。

ecc algorithm online:https://8gwifi.org/ecfunctions.jsp

word/media/image33.png

1. 椭圆曲线参数(Curve)

ECC 依赖于特定的 椭圆曲线(Elliptic Curves),不同曲线有不同的安全性和性能。

曲线名称密钥长度(bit)等效 RSA说明
secp160r1160-bitRSA-1024早期曲线,已不推荐
secp192r1 (NIST P-192)192-bitRSA-1536安全性不足
secp256r1 (NIST P-256)256-bitRSA-3072最低推荐曲线
secp384r1 (NIST P-384)384-bitRSA-7680更高安全性
secp521r1 (NIST P-521)521-bitRSA-15360超高安全级别
Curve25519256-bitRSA-3072高效安全,现代推荐
Curve448448-bitRSA-7680高安全性,适合长期使用
NIST P-256 和 Curve25519 是当前最常用的 ECC 曲线。

2. 公私钥(Private Key & Public Key)

  • 私钥(Private Key):随机生成的 256-bit (P-256) 或 384-bit (P-384) 大整数,用于解密或签名。

  • 公钥(Public Key):私钥乘以椭圆曲线基点 G 生成,即 Public Key = Private Key × G,用于加密或验证签名。

pip install cryptography

生成 ECC 密钥对,并保存到文件

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization

# 生成 ECC P-256(secp256r1)私钥
private_key = ec.generate_private_key(ec.SECP256R1())

# 导出私钥
pem_private = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption()
)

# 导出公钥
public_key = private_key.public_key().public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)

print("ECC 私钥:", pem_private.decode())
print("ECC 公钥:", public_key.decode())

3. ECDH(椭圆曲线 Diffie-Hellman)共享密钥

ECC 本身不能直接加密数据,而是使用 ECDH(Elliptic Curve Diffie-Hellman) 进行密钥交换:

  • 发送方和接收方分别生成自己的密钥对。

  • 通过 exchange() 方法,使用自己的 私钥 和对方的 公钥 计算 共享密钥:

shared_secret = private_key.exchange(ec.ECDH(), public_key)
  • 共享密钥不能直接用作 AES 密钥,需要通过 HKDF 进行密钥派生。

4. HKDF(密钥派生函数)

HKDF(HMAC-based Key Derivation Function) 用于从 ECDH 共享密钥 生成对称密钥(如 AES 密钥):

  • 输入:ECDH 共享密钥

  • 输出:固定长度的 AES 密钥(128-bit / 256-bit)

示例代码:

from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes

derived_key = HKDF(
    algorithm=hashes.SHA256(),
    length=32,  # 生成 32 字节的 AES-256 密钥
    salt=None,
    info=b"ECC Encryption",
).derive(shared_secret)

5. 对称加密(AES-GCM)

ECC 生成的密钥用于 AES-GCM 加密,需要以下参数:

  • IV(初始化向量):随机 12 字节,防止重放攻击

  • Tag(认证标签):AES-GCM 生成的 16 字节数据,用于数据完整性验证

示例代码:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import os

iv = os.urandom(12)  # 生成随机 IV
cipher = Cipher(algorithms.AES(derived_key), modes.GCM(iv))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(b"Hello, ECC!") + encryptor.finalize()

相关参数说明

参数名作用
Curve椭圆曲线类型(如 secp256r1, Curve25519)
Private Key私钥,大整数(用于解密 / 签名)
Public Key公钥,由 Private Key × G 计算(用于加密 / 验证)
ECDH Secret共享密钥,由 私钥 × 对方公钥计算
HKDF Key通过 HKDF 从共享密钥派生 AES 密钥
IV(Nonce)AES-GCM 加密时使用的随机值(防重放)
TagAES-GCM 认证标签(防篡改)
结论:ECC 主要用于安全的密钥交换,而不是直接加密数据!

完整示例代码

ECC 本身不能直接加密大数据,通常与 ECIES(椭圆曲线集成加密方案) 结合使用。

ECIES 结合了 非对称 + 对称加密:

  1. 使用 ECC 计算共享密钥(ECDH)

  2. 用共享密钥派生 AES 密钥(HKDF)

  3. 使用 AES 进行数据加密

  4. 发送加密数据 + 发送者的临时公钥(接收方可计算相同共享密钥)

下面使用 cryptography 库的 ECIES + AES-GCM 进行加密解密。

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import os

# 加密数据
def ecc_encrypt(public_key, plaintext):
    # 生成临时密钥对
    ephemeral_key = ec.generate_private_key(ec.SECP256R1())
    shared_secret = ephemeral_key.exchange(ec.ECDH(), public_key)

    # 通过 HKDF 生成对称密钥
    derived_key = HKDF(
        algorithm=hashes.SHA256(),
        length=32,  # AES-256 密钥
        salt=None,
        info=b"ECC Encryption",
    ).derive(shared_secret)

    # 生成随机 IV
    iv = os.urandom(12)

    # 使用 AES-GCM 进行加密
    cipher = Cipher(algorithms.AES(derived_key), modes.GCM(iv))
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()

    return ephemeral_key.public_key(), iv, encryptor.tag, ciphertext

# 解密数据
def ecc_decrypt(private_key, ephemeral_public_key, iv, tag, ciphertext):
    shared_secret = private_key.exchange(ec.ECDH(), ephemeral_public_key)

    # 通过 HKDF 生成对称密钥
    derived_key = HKDF(
        algorithm=hashes.SHA256(),
        length=32,  # AES-256 密钥
        salt=None,
        info=b"ECC Encryption",
    ).derive(shared_secret)

    # 使用 AES-GCM 进行解密
    cipher = Cipher(algorithms.AES(derived_key), modes.GCM(iv, tag))
    decryptor = cipher.decryptor()
    return decryptor.update(ciphertext) + decryptor.finalize()

# 读取 ECC 公钥和私钥
with open("ecc_private_key.pem", "rb") as f:
    private_key = serialization.load_pem_private_key(f.read(), password=None)

with open("ecc_public_key.pem", "rb") as f:
    public_key = serialization.load_pem_public_key(f.read())

# 加密
plaintext = b"Hello, ECC Encryption!"
ephemeral_public_key, iv, tag, ciphertext = ecc_encrypt(public_key, plaintext)
print(f"✅ 加密成功: {ciphertext.hex()}")

# 解密
decrypted_text = ecc_decrypt(private_key, ephemeral_public_key, iv, tag, ciphertext)
print(f"✅ 解密成功: {decrypted_text.decode()}")

输出如下:

✅ 加密成功: b1ab21c4ce2485e57c4313cd1b7107d6907eaf0500d0
✅ 解密成功: Hello, ECC Encryption!

RSA vs. ECC

对比项RSA 2048ECC 256
安全性传统但安全同样安全但更高效
密钥长度2048 位256 位
计算速度快(适用于移动设备)
应用场景电子签名、SSL区块链、移动安全

现代密码学趋势:RSA 2048 仍然可用,但计算较慢,ECC 256 位 ≈ RSA 3072 位,性能更优

压缩算法

压缩算法是一种减少数据大小的方法,通过去除冗余信息或高效编码,以降低存储和传输的成本。压缩算法广泛用于文件存储、数据传输、多媒体处理等领域。

Gzip

Gzip(GNU zip) 是一种无损压缩算法和文件格式,广泛用于文件压缩、Web 传输优化等场景。它基于 DEFLATE 算法(结合 LZ77 + Huffman 编码),可以高效地压缩文本和二进制数据。

可以看到输入数据长度有 876,经过 Gzip 压缩后只有 51。

word/media/image34.png

Gzip 压缩数据前缀固定的是 1f 8b

word/media/image35.png

import gzip

data = b"Hello, Gzip! " * 10  # 需要压缩的数据

# 压缩
compressed = gzip.compress(data)
print("Compressed:", compressed)

# 解压
decompressed = gzip.decompress(compressed)
print("Decompressed:", decompressed.decode())

输出如下:

Compressed: b'\x1f\x8b\x08\x00z\xb7\xc9g\x02\xff\xf3H\xcd\xc9\xc9\xd7Qp\xaf\xca,PT\xf0\x18\x08\x0e\x00\xbb\xac\x886\x82\x00\x00\x00'
Decompressed: Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! Hello, Gzip! 

Zlib

Zlib 是一种无损数据压缩库,基于 DEFLATE 算法(LZ77 + Huffman 编码)。支持 流式处理,适用于网络传输(如 HTTP、WebSocket),Zlib 压缩数据可用于 Gzip(不同的是 Zlib 有头部信息)。

Zlib 压缩数据默认前缀是 78 9c,不过 Zlib 有 10 个不同的压缩等级,不同等级前缀是不一样的。

word/media/image36.png

如果不指定 level,Zlib 默认使用 level=6,在压缩率和速度之间取得平衡。

何时选择不同的压缩级别?

  • level=1 适用于 网络传输、流式压缩(如 HTTP 传输)。

  • level=6 默认值,适用于 一般用途(如日志压缩)。

  • level=9 适用于 长期存储,如数据库备份、归档文件。

import binascii
import zlib

data = b"Hello, Zlib! " * 100

# 使用不同级别进行压缩
compressed_fast = zlib.compress(data, level=1)  # 速度最快
compressed_default = zlib.compress(data)  # 默认
compressed_best = zlib.compress(data, level=9)  # 压缩率最高

# 打印前 10 个字节(文件头部分)
print("Level 1 头部:", binascii.hexlify(compressed_fast[:10]))
print("Level 默认 头部:", binascii.hexlify(compressed_default[:10]))
print("Level 9 头部:", binascii.hexlify(compressed_best[:10]))

print(f"原始大小: {len(data)} 字节")
print(f"快速压缩大小: {len(compressed_fast)} 字节")
print(f"最佳压缩大小: {len(compressed_best)} 字节")

输出如下:

Level 1 头部: b'7801f348cdc9c9d75188'
Level 默认 头部: b'789cf348cdc9c9d75188'
Level 9 头部: b'78daf348cdc9c9d75188'
原始大小: 1300 字节
快速压缩大小: 35 字节
最佳压缩大小: 32 字节

从输出可以看到,压缩等级不一样,header 也不一样。

Zip

ZIP 是一种无损压缩格式,用于打包多个文件并进行压缩。ZIP 并不是单一算法,而是支持多种压缩算法(如 Deflate、BZip2、LZMA 等),其中最常用的是 DEFLATE(LZ77 + Huffman 编码)。

前缀是 PK(50 4B)

word/media/image37.png

ZIP 压缩文件

import zipfile

# 创建 ZIP 文件并添加文件
with zipfile.ZipFile("example.zip", "w", zipfile.ZIP_DEFLATED) as zipf:
    zipf.write("1.txt")  # 添加文件
    zipf.write("2.txt")  # 添加文件

ZIP 解压文件

import zipfile

# 解压 ZIP 文件
with zipfile.ZipFile("example.zip", "r") as zipf:
    zipf.extractall("example")  # 解压到文件夹

读取 ZIP 内文件

import zipfile

with zipfile.ZipFile("example.zip", "r") as zipf:
    file_list = zipf.namelist()  # 获取 ZIP 内文件列表
    print("ZIP 内文件:", file_list)

    # 读取某个文件的内容
    with zipf.open("1.txt") as f:
        print(f.read().decode())  # 读取并解码

使用不同算法进行 ZIP 压缩

import zipfile

# 创建 ZIP 文件,选择不同的压缩算法
def create_zip(compression_method, zip_filename="output.zip"):
    with zipfile.ZipFile(zip_filename, "w", compression=compression_method) as zipf:
        zipf.write("1.txt")  # 压缩文件1
        zipf.write("2.txt")  # 压缩文件2
    print(f"文件已压缩为 {zip_filename},压缩方式: {compression_method}")

# 使用不同压缩算法
create_zip(zipfile.ZIP_STORED, "stored.zip")     # 无压缩
create_zip(zipfile.ZIP_DEFLATED, "deflated.zip") # 使用 Deflate(默认)
create_zip(zipfile.ZIP_BZIP2, "bzip2.zip")       # 使用 BZip2
create_zip(zipfile.ZIP_LZMA, "lzma.zip")         # 使用 LZMA(最高压缩率)

不同的压缩算法文件头都是 PK(50 4B)

word/media/image38.png

Tar

Tar(Tape Archive) 是一种用于打包多个文件的归档格式,常用于Linux/Unix 系统。Tar 本身不压缩数据,但可以与 Gzip、Bzip2、LZMA 等压缩算法结合使用,形成 .tar.gz、.tar.bz2、.tar.xz 等格式。

Tar 归档文件由多个文件头(Header)+ 文件数据组成:

[文件头] + [文件内容] + [文件头] + [文件内容] + ...
  • 文件头(Header):包含文件名、大小、权限、时间戳等信息。

  • 文件数据(Content):文件的原始内容(未压缩)。

简单的打包算法,数据还是原始数据。

word/media/image39.png

创建 .tar(仅打包,不压缩)

import tarfile

# 创建 tar 归档(不压缩)
with tarfile.open("archive.tar", "w") as tar:
    tar.add("1.txt")  # 添加文件
    tar.add("2.txt")  # 添加文件
    tar.add("example")  # 添加文件夹(包含其中所有文件)

创建 .tar.gz(使用 Gzip 压缩)

import tarfile

# 创建 tar.gz 归档
with tarfile.open("archive.tar.gz", "w:gz") as tar:
    tar.add("1.txt")  # 添加文件
    tar.add("2.txt")  # 添加文件

创建 .tar.bz2(使用 Bzip2 压缩,压缩率更高)

import tarfile

# 创建 tar.bz2 归档(Bzip2 压缩)
with tarfile.open("archive.tar.bz2", "w:bz2") as tar:
    tar.add("1.txt")
    tar.add("2.txt")
    tar.add("example")

创建 .tar.xz(使用 LZMA/XZ 压缩,最高压缩率)

import tarfile

# 创建 tar.xz 归档(LZMA 压缩)
with tarfile.open("archive.tar.xz", "w:xz") as tar:
    tar.add("1.txt")
    tar.add("2.txt")
    tar.add("example")

7z

7z 是 7-Zip 压缩工具所使用的压缩格式,具有高压缩率、多种压缩算法支持等特点,被广泛应用于大文件和批量文件的压缩。

前缀是 7z(37 7A)

word/media/image40.png

安装 py7zr

pip install py7zr

使用 py7zr 进行 7z 压缩

import py7zr

# 创建 7z 压缩包
with py7zr.SevenZipFile('example.7z', 'w') as archive:
    archive.write('1.txt')  # 添加单个文件
    archive.writeall('example')  # 添加整个文件夹

解压 7z 文件

import py7zr

# 解压 7z 文件
with py7zr.SevenZipFile('example.7z', 'r') as archive:
    archive.extractall(path='example')