常用加解密算法介绍

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

常见加解密工具

CyberChef

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

openssl

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

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

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

cryptopp

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

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

项目地址:github.com/weidai11/cr...

chilkat

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

下载地址:www.chilkatsoft.com/downloads.a...

编码算法

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

Hex

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

ini 复制代码
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 编码的内容转换回原始字符的过程。

ini 复制代码
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)

输出如下:

perl 复制代码
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 攻击(避免 被浏览器解析执行)。

常见 HTML 实体

ini 复制代码
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)

输出如下:

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

Base64

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

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

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

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

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

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

当遇到这种情况就需要从代码中查找对应的索引表了

ini 复制代码
import base64

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

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

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

输出如下:

ini 复制代码
Base64 编码: SGVsbG8sIEJhc2U2NCE=
Base64 解码: Hello, Base64!

Hash 算法

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

CRC-32

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

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

ini 复制代码
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 位的字符串

Hex 数据

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

ini 复制代码
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 位的字符串

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

ini 复制代码
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 位的字符串

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

ini 复制代码
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,密钥可能有也可能没有

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

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

ini 复制代码
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 差不多

ini 复制代码
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)。

ini 复制代码
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())

输出如下:

makefile 复制代码
密文: b'bOFFE'
解密: Hello

RC4

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

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

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

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

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

ini 复制代码
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())

输出如下:

makefile 复制代码
密文: 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 个字节

Python 的 pycryptodome 库提供了 DES 实现:

复制代码
pip install pycryptodome

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

  • 特点:

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

  • 不需要 IV。

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

Python 代码示例

ini 复制代码
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())

输出如下:

makefile 复制代码
密文: 583d732b24aa664ec46b788d096a2da5
解密: Hello, DES!

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

  • 特点

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

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

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

Python 代码示例

ini 复制代码
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 代码示例

ini 复制代码
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 代码示例

ini 复制代码
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 代码示例

ini 复制代码
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())

输出如下:

objectivec 复制代码
CTR 密文: fe79bfdfe81bf8306254a8
CTR 解密: Hello, DES!

DES 各模式对比

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

3DES(Triple DES)

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

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

ini 复制代码
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字节) 位密钥。

特性 描述
加密方式 对称加密(加密和解密使用相同的密钥)
分组长度 128 位(16 字节)
密钥长度 128 位、192 位、256 位(分别对应 10、12、14 轮加密)
安全性 目前无已知有效攻击,比 3DES 更安全
运算模式 支持 ECB、CBC、CFB、OFB、CTR 等模式
ini 复制代码
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 加密库 :gmssl.org/docs/sm4.ht...

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

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

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

特性 描述
算法类型 对称加密(加密解密使用相同密钥)
分组大小 128 位(16 字节)
密钥长度 128 位(16 字节)
加密轮数 32 轮
安全性 比 DES/3DES 更安全,可替代 AES-128
运算模式 支持 ECB、CBC、CFB、OFB、CTR
复制代码
pip install gmssl
ini 复制代码
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:emn178.github.io/online-tool...

常见密钥长度

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

使用公钥加密数据

RSA Encrypt:emn178.github.io/online-tool...

使用私钥解密数据

RSA Decrypt:emn178.github.io/online-tool...

生成 RSA 密钥

python 复制代码
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 加密

python 复制代码
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())

输出如下:

bash 复制代码
密文: 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 密钥

python 复制代码
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())

输出如下:

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

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

ini 复制代码
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())

输出如下:

makefile 复制代码
解密后的数据: Hello, RSA + AES!

ECC

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

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

1. 椭圆曲线参数(Curve)

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

曲线名称 密钥长度(bit) 等效 RSA 说明
secp160r1 160-bit RSA-1024 早期曲线,已不推荐
secp192r1 (NIST P-192) 192-bit RSA-1536 安全性不足
secp256r1 (NIST P-256) 256-bit RSA-3072 最低推荐曲线
secp384r1 (NIST P-384) 384-bit RSA-7680 更高安全性
secp521r1 (NIST P-521) 521-bit RSA-15360 超高安全级别
Curve25519 256-bit RSA-3072 高效安全,现代推荐
Curve448 448-bit RSA-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 密钥对,并保存到文件

ini 复制代码
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() 方法,使用自己的 私钥 和对方的 公钥 计算 共享密钥:

ini 复制代码
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)

示例代码:

ini 复制代码
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 字节数据,用于数据完整性验证

示例代码:

ini 复制代码
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 加密时使用的随机值(防重放)
Tag AES-GCM 认证标签(防篡改)
结论:ECC 主要用于安全的密钥交换,而不是直接加密数据!

完整示例代码

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

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

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

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

  3. 使用 AES 进行数据加密

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

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

ini 复制代码
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 2048 ECC 256
安全性 传统但安全 同样安全但更高效
密钥长度 2048 位 256 位
计算速度 快(适用于移动设备)
应用场景 电子签名、SSL 区块链、移动安全

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

压缩算法

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

Gzip

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

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

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

ini 复制代码
import gzip

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

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

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

输出如下:

vbnet 复制代码
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 个不同的压缩等级,不同等级前缀是不一样的。

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

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

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

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

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

python 复制代码
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)} 字节")

输出如下:

bash 复制代码
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)

ZIP 压缩文件

python 复制代码
import zipfile

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

ZIP 解压文件

python 复制代码
import zipfile

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

读取 ZIP 内文件

python 复制代码
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 压缩

python 复制代码
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)

Tar

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

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

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

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

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

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

csharp 复制代码
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 压缩)

csharp 复制代码
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 压缩,压缩率更高)

csharp 复制代码
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 压缩,最高压缩率)

csharp 复制代码
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)

安装 py7zr

复制代码
pip install py7zr

使用 py7zr 进行 7z 压缩

python 复制代码
import py7zr

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

解压 7z 文件

python 复制代码
import py7zr

# 解压 7z 文件
with py7zr.SevenZipFile('example.7z', 'r') as archive:
    archive.extractall(path='example')
相关推荐
LabVIEW开发3 分钟前
LabVIEW中算法开发的系统化解决方案与优化
算法·labview
chenyuhao20249 分钟前
链表面试题7之相交链表
数据结构·算法·链表·面试·c#
Pluchon20 分钟前
硅基计划2.0 学习总结 壹 Java初阶
java·开发语言·学习·算法
仙人掌_lz32 分钟前
理解多智能体深度确定性策略梯度MADDPG算法:基于python从零实现
python·算法·强化学习·策略梯度·rl
电报号dapp1191 小时前
区块链钱包开发全解析:从架构设计到安全生态构建
安全·web3·去中心化·区块链·智能合约
C_Liu_1 小时前
C语言:深入理解指针(3)
c语言·数据结构·算法
Spider Cat 蜘蛛猫2 小时前
【一】浏览器的copy as fetch和copy as bash的区别
javascript·ajax·bash·逆向·fetch
Frankabcdefgh2 小时前
前端进化论·JavaScript 篇 · 数据类型
javascript·安全·面试·数据类型·操作符·初学者·原理解析
智驱力人工智能2 小时前
AI智慧公园管理方案:用科技重塑市民的“夜游体验”
人工智能·科技·安全·边缘计算·视觉分析·人工智能云计算·垂钓检测
xindafu2 小时前
代码随想录算法训练营第三十八天|动态规划part6(完全背包2)
算法·动态规划