编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • ScriptHub 脚本工具箱
  • Python

  • Shell-Bash

  • 工具脚本

    • 工具脚本速查
    • 哈希校验
    • Base64编码
    • AES加解密
      • 一、AES 基础概念
      • 二、Python AES 加解密
        • 2.1 AES-CBC 模式——最常用
        • 2.2 AES-GCM 模式——自带认证(推荐新项目用)
        • 2.3 PBKDF2——从密码派生密钥
      • 三、Shell openssl AES
      • 四、实战:文件安全加解密工具
    • RSA签名验签
    • JWT令牌
    • JSON与YAML
    • XML与CSV
    • 编码转义
    • 图片转换
    • 文档转换
    • 批量重命名
    • 分割合并
    • 目录同步
    • 文件监控
    • 压缩归档
    • 文件去重
    • cURL速查
    • HTTP调试
    • 端口DNS
    • 抓包代理
  • ScriptHub
  • 工具脚本
杨充
2022-06-04
目录

AES加解密

# AES加解密

对称加密标准——CBC/GCM 模式、PBKDF2 密钥派生、文件加解密、Shell openssl 一行命令。

# 一、AES 基础概念

AES = Advanced Encryption Standard(高级加密标准)
对称加密 = 加密和解密使用同一个密钥

关键参数:
  密钥(Key):16/24/32 字节 → AES-128/192/256
  初始向量(IV):16 字节,CBC/GCM 模式必需
  模式:CBC(经典) | GCM(推荐——自带认证) | ECB(不安全,不要用)
1
2
3
4
5
6
7

# 二、Python AES 加解密

# 2.1 AES-CBC 模式——最常用

pip install pycryptodome
1
#!/usr/bin/env python3
"""AES-256-CBC 加解密——生产级写法"""
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import base64, os

# ---- 生成密钥和 IV ----
def generate_key_iv():
    """生成随机密钥(32 字节=256 位)和 IV(16 字节)"""
    return get_random_bytes(32), get_random_bytes(16)

# ---- 加密 ----
def aes_cbc_encrypt(plaintext: str, key: bytes, iv: bytes) -> str:
    """加密 → Base64(方便存储传输)"""
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(pad(plaintext.encode('utf-8'), AES.block_size))
    return base64.b64encode(ciphertext).decode()

# ---- 解密 ----
def aes_cbc_decrypt(encoded: str, key: bytes, iv: bytes) -> str:
    """Base64 → 解密"""
    ciphertext = base64.b64decode(encoded)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(ciphertext), AES.block_size).decode('utf-8')

# ---- 演示 ----
if __name__ == '__main__':
    key, iv = generate_key_iv()
    plaintext = "Hello, 这是机密数据!"

    encrypted = aes_cbc_encrypt(plaintext, key, iv)
    print(f"密文(Base64): {encrypted}")

    decrypted = aes_cbc_decrypt(encrypted, key, iv)
    print(f"解密: {decrypted}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 2.2 AES-GCM 模式——自带认证(推荐新项目用)

#!/usr/bin/env python3
"""AES-256-GCM——自带完整性校验,防篡改"""
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import base64, json

def aes_gcm_encrypt(plaintext: str, key: bytes) -> dict:
    """GCM 加密——返回密文 + nonce + tag(都是 Base64)"""
    cipher = AES.new(key, AES.MODE_GCM)
    ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode('utf-8'))
    return {
        'ciphertext': base64.b64encode(ciphertext).decode(),
        'nonce':      base64.b64encode(cipher.nonce).decode(),
        'tag':        base64.b64encode(tag).decode()       # 认证标签
    }

def aes_gcm_decrypt(package: dict, key: bytes) -> str:
    """GCM 解密——自动验证 tag,被篡改会抛异常"""
    nonce = base64.b64decode(package['nonce'])
    tag   = base64.b64decode(package['tag'])
    cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
    ciphertext = base64.b64decode(package['ciphertext'])
    return cipher.decrypt_and_verify(ciphertext, tag).decode('utf-8')

# ---- GCM vs CBC ----
# GCM 额外提供了「认证标签(tag)」——如果密文被篡改,解密时直接抛异常
# 不需要 HMAC 了——GCM 自带防篡改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 2.3 PBKDF2——从密码派生密钥

用户密码 ≠ 密钥。用 PBKDF2 从任意密码安全派生 32 字节 AES 密钥:

#!/usr/bin/env python3
"""PKCS#5 PBKDF2——把人类可记的密码变成 32 字节密钥"""
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
import base64

def derive_key(password: str, salt: bytes = None, iterations=600_000):
    """从密码 + salt 派生出 AES-256 密钥"""
    if salt is None:
        salt = get_random_bytes(16)
    key = PBKDF2(password, salt, dkLen=32, count=iterations)
    return key, salt

# ---- 完整加密流程 ----
password = "my-strong-password"
salt = get_random_bytes(16)
aes_key, _ = derive_key(password, salt)
print(f"AES Key (hex): {aes_key.hex()}")

# 存储时需要保存 salt——解密时用它复原同一个密钥
# 推荐迭代次数:600000+(OWASP 2023 建议)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 三、Shell openssl AES

#!/bin/bash

# ===== AES-256-CBC 加密文件 =====
# 加密
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 \
    -in secret.txt -out secret.txt.enc \
    -pass pass:"my-password"
# -pbkdf2: 用 PBKDF2 派生密钥(否则有警告)
# -iter: 迭代次数

# 解密
openssl enc -d -aes-256-cbc -pbkdf2 -iter 100000 \
    -in secret.txt.enc -out secret_decrypted.txt \
    -pass pass:"my-password"

# ===== 字符串加密(管道)=====
echo "机密数据" | openssl enc -aes-256-cbc -a -pbkdf2 -iter 100000 \
    -pass pass:"pwd"          # -a = Base64 输出
echo "密文Base64" | openssl enc -d -aes-256-cbc -a -pbkdf2 -iter 100000 \
    -pass pass:"pwd"

# ⚠️ 密码不要在命令行写(会被 ps 看到)
# 用 -pass env:MY_PASS 从环境变量读取
export MY_PASS="my-secret"
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 \
    -in file.txt -out file.enc -pass env:MY_PASS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 四、实战:文件安全加解密工具

#!/usr/bin/env python3
"""
文件 AES-256 加解密脚本
用法:
  encrypt: python file_crypt.py enc secret.txt password
  decrypt: python file_crypt.py dec secret.txt.enc password
"""
import sys, os, json, base64, struct
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes

SALT_SIZE = 16
IV_SIZE   = 16
ITERATIONS = 600_000

def encrypt_file(filepath: str, password: str):
    """加密文件 → .enc 格式(salt+iv+ciphertext)"""
    with open(filepath, 'rb') as f:
        plaintext = f.read()

    salt = get_random_bytes(SALT_SIZE)
    key  = PBKDF2(password, salt, dkLen=32, count=ITERATIONS)
    iv   = get_random_bytes(IV_SIZE)
    cipher = AES.new(key, AES.MODE_CBC, iv)

    # PKCS7 填充
    pad_len = 16 - (len(plaintext) % 16)
    plaintext += bytes([pad_len]) * pad_len

    ciphertext = cipher.encrypt(plaintext)
    # 输出格式:salt(16) + iv(16) + ciphertext(...)
    with open(filepath + '.enc', 'wb') as f:
        f.write(salt + iv + ciphertext)
    print(f"✅ {filepath} → {filepath}.enc")

def decrypt_file(filepath: str, password: str):
    """解密 .enc 文件"""
    with open(filepath, 'rb') as f:
        data = f.read()
    salt, iv = data[:SALT_SIZE], data[SALT_SIZE:SALT_SIZE+IV_SIZE]
    ciphertext = data[SALT_SIZE+IV_SIZE:]

    key = PBKDF2(password, salt, dkLen=32, count=ITERATIONS)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(ciphertext)

    # 去 PKCS7 填充
    pad_len = plaintext[-1]
    plaintext = plaintext[:-pad_len]

    outpath = filepath.rsplit('.enc', 1)[0] if filepath.endswith('.enc') else filepath + '.dec'
    with open(outpath, 'wb') as f:
        f.write(plaintext)
    print(f"✅ {filepath} → {outpath}")

if __name__ == '__main__':
    cmd, path, pwd = sys.argv[1], sys.argv[2], sys.argv[3]
    {'enc': encrypt_file, 'dec': decrypt_file}[cmd](path, pwd)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#工具#加密
上次更新: 2026/06/17, 12:47:39
Base64编码
RSA签名验签

← Base64编码 RSA签名验签→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式