编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • 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加解密
    • RSA签名验签
      • 一、RSA 核心概念
      • 二、Python — cryptography 库
        • 2.1 密钥生成
        • 2.2 签名与验签
        • 2.3 RSA 加密/解密(小数据)
      • 三、Shell — OpenSSL RSA
      • 四、实战:API 请求签名工具
    • JWT令牌
    • JSON与YAML
    • XML与CSV
    • 编码转义
    • 图片转换
    • 文档转换
    • 批量重命名
    • 分割合并
    • 目录同步
    • 文件监控
    • 压缩归档
    • 文件去重
    • cURL速查
    • HTTP调试
    • 端口DNS
    • 抓包代理
  • ScriptHub
  • 工具脚本
杨充
2022-11-01
目录

RSA签名验签

# RSA签名验签

非对称加密双璧——公钥加密/验签、私钥解密/签名。API 签名验证、SSH 密钥管理、软件许可。

# 一、RSA 核心概念

非对称 = 两把钥匙
  私钥 (Private Key)  —— 保密,用来签名和解密
  公钥 (Public Key)   —— 公开,用来验签和加密

签名流程:
  发送方用「私钥」签名 → 接收方用「公钥」验签
  → 证明"内容来自私钥持有者 + 未被篡改"

RSA 密钥长度:2048(最低)/ 3072 / 4096 位
1
2
3
4
5
6
7
8
9

# 二、Python — cryptography 库

pip install cryptography
1

# 2.1 密钥生成

#!/usr/bin/env python3
"""生成 RSA 密钥对并保存为 PEM 文件"""
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

# ---- 生成密钥 ----
private_key = rsa.generate_private_key(
    public_exponent=65537,          # 标准公钥指数
    key_size=2048,                  # 2048 位(>=2048)
)

# ---- 导出私钥(PEM 格式)----
private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption()  # 可加密
)
with open('private.pem', 'wb') as f:
    f.write(private_pem)
print("✅ 私钥: private.pem")

# ---- 导出公钥 ----
public_key = private_key.public_key()
public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open('public.pem', 'wb') as f:
    f.write(public_pem)
print("✅ 公钥: public.pem")
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

# 2.2 签名与验签

#!/usr/bin/env python3
"""RSA 签名 + 验签——完整流程"""
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
import base64

# ---- 加载密钥 ----
def load_private_key(path='private.pem'):
    with open(path, 'rb') as f:
        return serialization.load_pem_private_key(f.read(), password=None)

def load_public_key(path='public.pem'):
    with open(path, 'rb') as f:
        return serialization.load_pem_public_key(f.read())

# ---- 签名 ----
def sign(message: bytes, private_key) -> str:
    """用私钥签名,返回 Base64 签名"""
    signature = private_key.sign(
        message,
        padding.PSS(                          # PSS = 推荐的填充方案
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    return base64.b64encode(signature).decode()

# ---- 验签 ----
def verify(message: bytes, signature_b64: str, public_key) -> bool:
    """用公钥验证签名"""
    try:
        signature = base64.b64decode(signature_b64)
        public_key.verify(
            signature,
            message,
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH),
            hashes.SHA256()
        )
        return True
    except Exception:
        return False

# ---- 演示 ----
if __name__ == '__main__':
    priv = load_private_key()
    pub  = load_public_key()

    msg = b'{"order_id":"12345","amount":99.99}'
    sig = sign(msg, priv)
    print(f"签名: {sig[:60]}...")

    ok = verify(msg, sig, pub)
    print(f"验签通过: {ok}")    # True

    # 篡改检测
    tampered = b'{"order_id":"12345","amount":0.01}'
    print(f"篡改检测: {verify(tampered, sig, pub)}")  # False
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

# 2.3 RSA 加密/解密(小数据)

#!/usr/bin/env python3
"""RSA 加密——只适合小数据(<密钥长度-填充),通常配合 AES 使用"""
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
import base64

def rsa_encrypt(plaintext: bytes, public_key) -> str:
    """公钥加密——用 OAEP 填充"""
    ct = public_key.encrypt(
        plaintext,
        padding.OAEP(mgf=padding.MGF1(hashes.SHA256()),
                     algorithm=hashes.SHA256(), label=None)
    )
    return base64.b64encode(ct).decode()

def rsa_decrypt(ciphertext_b64: str, private_key) -> bytes:
    """私钥解密"""
    ct = base64.b64decode(ciphertext_b64)
    return private_key.decrypt(
        ct,
        padding.OAEP(mgf=padding.MGF1(hashes.SHA256()),
                     algorithm=hashes.SHA256(), label=None)
    )

# 典型用途:RSA 加密 AES 密钥(密钥交换),
# 大数据用 AES 加密
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

# 三、Shell — OpenSSL RSA

#!/bin/bash

# ===== 生成 RSA 私钥 =====
openssl genrsa -out private.pem 2048

# ===== 提取公钥 =====
openssl rsa -in private.pem -pubout -out public.pem

# ===== 签名 =====
echo -n "message to sign" | openssl dgst -sha256 -sign private.pem \
    | base64 > signature.txt

# ===== 验签 =====
openssl dgst -sha256 -verify public.pem -signature \
    <(base64 -d signature.txt) <<< "message to sign"
# 输出:Verified OK  ← 签名有效

# ===== RSA 加密/解密 =====
# 公钥加密(OpenSSL 3.x 用 pkeyutl)
openssl pkeyutl -encrypt -pubin -inkey public.pem \
    -in secret.txt -out secret.txt.enc
# 私钥解密
openssl pkeyutl -decrypt -inkey private.pem \
    -in secret.txt.enc -out secret_decrypted.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 四、实战:API 请求签名工具

#!/usr/bin/env python3
"""
为 HTTP API 请求添加 RSA 签名——防篡改 + 身份认证
客户端:用私钥签名请求体
服务端:用公钥验证签名
"""
import json, base64, hashlib
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

# ---- 加载密钥 ----
def load_key(path, is_private=False):
    with open(path, 'rb') as f:
        data = f.read()
    if is_private:
        return serialization.load_pem_private_key(data, password=None)
    return serialization.load_pem_public_key(data)

# ---- 客户端:生成带签名的请求 ----
def sign_request(body: dict, private_key_path: str) -> dict:
    """把请求体序列化→签名→附加到 headers"""
    payload = json.dumps(body, separators=(',', ':')).encode()
    priv = load_key(private_key_path, is_private=True)
    signature = priv.sign(
        payload,
        padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                    salt_length=padding.PSS.MAX_LENGTH),
        hashes.SHA256()
    )
    return {
        'body': body,
        'headers': {
            'X-Signature': base64.b64encode(signature).decode(),
            'Content-Type': 'application/json'
        }
    }

# ---- 服务端:验证签名 ----
def verify_request(body: dict, signature_b64: str, public_key_path: str) -> bool:
    """验证请求签名"""
    payload = json.dumps(body, separators=(',', ':')).encode()
    pub = load_key(public_key_path)
    try:
        pub.verify(
            base64.b64decode(signature_b64),
            payload,
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH),
            hashes.SHA256()
        )
        return True
    except Exception:
        return False

# ---- 演示 ----
if __name__ == '__main__':
    req = sign_request(
        {"order_id": "12345", "amount": 99.99},
        'private.pem'
    )
    print(f"签名请求: {json.dumps(req, indent=2)}")

    ok = verify_request(req['body'], req['headers']['X-Signature'], 'public.pem')
    print(f"服务端验签: {'✅ 通过' if ok else '❌ 失败'}")
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
60
61
62
63
64
#工具#加密
上次更新: 2026/06/17, 12:47:39
AES加解密
JWT令牌

← AES加解密 JWT令牌→

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