apppublic/aidocs/rsa_key_rw.md
2025-10-05 11:23:33 +08:00

389 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# RSA 密钥管理与签名验证工具技术文档
本项目提供一个基于 `cryptography` 库的轻量级 RSA 加密、解密、签名与验证功能封装支持多种密钥格式PEM、PKCS#1、PKCS#8、OpenSSH的加载与写入。适用于需要安全地处理 RSA 公私钥及数字签名的应用场景。
---
## 📦 依赖库
```bash
pip install cryptography
```
> **注意**`cryptography` 是一个使用 CFFI 绑定 OpenSSL 的密码学库,需确保系统中已安装必要的编译工具或预编译包。
---
## 🧩 模块功能概览
| 功能 | 描述 |
|------|------|
| `_load_private_key` | 从文件加载私钥(支持 PEM 和 OpenSSH 格式) |
| `_load_public_key` | 从文件加载公钥(支持 PEM 和 OpenSSH 格式) |
| `_write_private_key` | 将私钥写入文件(支持 PKCS#1, PKCS#8, OpenSSH 格式) |
| `_write_public_key` | 将公钥写入文件(支持 PEM, OpenSSH 格式) |
| `_sign` / `_verify` | 使用私钥签名和公钥验证数据SHA256 + PKCS1v15 |
| `RSAer` 类 | 面向对象接口,集成密钥生成、读写、签名/验证等功能 |
---
## 🔐 私钥操作
### `_load_private_key(filepath: str, password: bytes = None) → RSAPrivateKey`
从指定路径加载私钥文件,自动识别格式并返回对应的 `RSAPrivateKey` 对象。
#### 参数:
- `filepath` (str): 私钥文件路径。
- `password` (bytes, optional): 解密加密私钥所需的口令(字节类型),若未加密可省略。
#### 支持格式:
| 开头标识 | 格式说明 |
|--------|---------|
| `-----BEGIN OPENSSH PRIVATE KEY-----` | OpenSSH 私钥格式 |
| `-----BEGIN RSA PRIVATE KEY-----``-----BEGIN PRIVATE KEY-----` | PEM 编码的私钥PKCS#1 或 PKCS#8 |
#### 返回值:
- `RSAPrivateKey`: 成功时返回私钥对象。
#### 异常:
- `ValueError`: 不支持的私钥格式。
- `TypeError`: 密码错误或格式损坏。
#### 示例:
```python
private_key = _load_private_key("id_rsa", password=b"mypass")
```
---
### `_write_private_key(key, filepath, fmt="pkcs8", password: bytes = None)`
将私钥对象写入文件,支持加密保存。
#### 参数:
- `key` (`RSAPrivateKey`): 要写入的私钥对象。
- `filepath` (str): 输出文件路径。
- `fmt` (str): 输出格式,可选 `"pkcs8"`(默认)、`"pkcs1"``"openssh"`
- `password` (bytes, optional): 若提供,则使用最佳可用算法加密私钥。
#### 支持格式:
| `fmt` 值 | 格式描述 |
|--------|----------|
| `pkcs8` | PEM 编码的 PKCS#8 格式(推荐) |
| `pkcs1` | PEM 编码的传统 RSA 私钥(仅限 RSA |
| `openssh` | OpenSSH 原生私钥格式(兼容 OpenSSH 工具链) |
#### 注意事项:
-`password` 不为 `None` 时,私钥将被加密存储。
- 所有输出均为二进制模式写入。
#### 示例:
```python
_write_private_key(private_key, "private_encrypted.pem", fmt="pkcs8", password=b"secret123")
```
---
## 🔍 公钥操作
### `_load_public_key(filepath: str) → RSAPublicKey`
从文件加载公钥,自动识别格式。
#### 参数:
- `filepath` (str): 公钥文件路径。
#### 支持格式:
| 文件内容开头 | 格式 |
|-------------|------|
| `ssh-rsa`, `ssh-ed25519` 等 | OpenSSH 公钥格式 |
| `-----BEGIN PUBLIC KEY-----` | PEM 编码的标准公钥SubjectPublicKeyInfo |
#### 返回值:
- `RSAPublicKey`: 成功时返回公钥对象。
#### 异常:
- `ValueError`: 不支持的公钥格式。
#### 示例:
```python
public_key = _load_public_key("id_rsa.pub")
```
---
### `_write_public_key(public_key, filepath, fmt="pem")`
将公钥对象写入文件。
#### 参数:
- `public_key` (`RSAPublicKey`): 公钥对象。
- `filepath` (str): 输出文件路径。
- `fmt` (str): 输出格式,支持 `"pem"`(默认)或 `"openssh"`
#### 支持格式:
| `fmt` | 输出格式 |
|-------|---------|
| `pem` | PEM 编码的 X.509 公钥(标准格式) |
| `openssh` | OpenSSH 风格的单行公钥(如用于 `~/.ssh/authorized_keys` |
#### 示例:
```python
_write_public_key(public_key, "public.pem", fmt="pem")
_write_public_key(public_key, "id_rsa_openssh.pub", fmt="openssh")
```
---
## ✍️ 数字签名与验证
### `_sign(prikey, data: bytes) → bytes`
使用私钥对数据进行 SHA256 + PKCS1v15 签名。
#### 参数:
- `prikey` (`RSAPrivateKey`): 有效的 RSA 私钥。
- `data` (bytes): 待签名的原始数据。
#### 返回值:
- `bytes`: 签名结果(二进制)。
#### 算法细节:
- 哈希算法:`SHA-256`
- 填充方式:`PKCS1v15`
> ⚠️ 注:也可替换为更现代的 `PSS` 填充以增强安全性。
#### 示例:
```python
signature = _sign(private_key, b"Hello World")
```
---
### `_verify(pubkey, data: bytes, signature: bytes) → bool`
验证数据签名是否有效。
#### 参数:
- `pubkey` (`RSAPublicKey`): 对应的公钥。
- `data` (bytes): 原始数据。
- `signature` (bytes): 签名值。
#### 返回值:
- `True`: 验证成功。
- `False`: 验证失败(包括异常捕获)。
#### 内部机制:
- 使用与 `_sign` 相同的参数(`PKCS1v15`, `SHA256`)进行校验。
- 捕获 `InvalidSignature` 异常并返回 `False`
#### 示例:
```python
is_valid = _verify(public_key, b"Hello World", signature)
print(is_valid) # True or False
```
---
## 🧱 RSAer 类:高级封装接口
`RSAer` 提供面向对象的方式统一管理密钥与操作。
### 初始化
```python
rsa_tool = RSAer()
```
属性初始化为空:
- `self.prikey = None`
- `self.pubkey = None`
---
### `.create_key(keylen=2048)`
生成新的 RSA 密钥对。
#### 参数:
- `keylen` (int): 密钥长度,默认 `2048`,建议至少 2048 位。
#### 生成规则:
- 公共指数固定为 `65537`Fermat Prime行业标准
- 使用安全随机源生成大素数
#### 示例:
```python
rsa_tool.create_key(2048)
```
---
### `.write_private_key(filepath, fmt="pkcs8", password=None)`
导出私钥到文件。
#### 参数:
- `filepath`: 输出路径
- `fmt`: 格式(`pkcs8`, `pkcs1`, `openssh`
- `password`: 可选加密口令bytes
> ❗ 抛出异常:若 `self.prikey` 为 `None`
#### 示例:
```python
rsa_tool.write_private_key("mykey.pem", fmt="pkcs8", password=b"pass123")
```
---
### `.write_public_key(filepath, fmt="pem")`
导出公钥到文件。
#### 参数:
- `filepath`: 输出路径
- `fmt`: `pem``openssh`
> ⚠️ 自动从私钥推导公钥(如果尚未设置)
#### 示例:
```python
rsa_tool.write_public_key("mykey.pub", fmt="openssh")
```
---
### `.load_private_key(filepath, password=None)`
加载已有私钥。
#### 示例:
```python
rsa_tool.load_private_key("private.pem", password=None)
```
---
### `.load_public_key(filepath)`
加载已有公钥。
#### 示例:
```python
rsa_tool.load_public_key("public.pem")
```
---
### `.sign(data: bytes) → bytes`
使用当前私钥签名数据。
#### 示例:
```python
sig = rsa_tool.sign(b"Important message")
```
---
### `.verify(data: bytes, signature: bytes) → bool`
使用当前公钥验证签名。
#### 示例:
```python
valid = rsa_tool.verify(b"Important message", sig)
assert valid == True
```
---
### ❌ 待实现方法
以下两个方法在代码中声明但未实现:
```python
def encode(self, data):
def decode(self, data):
```
> 后续可根据需求补充 RSA 加解密功能(通常用于小数据块加密,如密钥传输)。
> 推荐使用 `padding.OAEP` 或 `PKCS1v15` 进行加密填充。
---
## 🧪 示例用法(主程序)
```python
if __name__ == '__main__':
# 示例:加载私钥和公钥
private_key = _load_private_key("path/to/private_key.pem", password=None)
public_key = _load_public_key("path/to/public_key.pub")
print("私钥类型:", type(private_key))
print("公钥类型:", type(public_key))
# 写出不同格式的私钥
_write_private_key(private_key, "private_pkcs8.pem", fmt="pkcs8")
_write_private_key(private_key, "private_pkcs1.pem", fmt="pkcs1")
_write_private_key(private_key, "private_openssh", fmt="openssh")
# 写出不同格式的公钥
_write_public_key(public_key, "public.pem", fmt="pem")
_write_public_key(public_key, "id_rsa.pub", fmt="openssh")
# 签名与验证
data = b"Secure message"
signature = _sign(private_key, data)
is_valid = _verify(public_key, data, signature)
print("Signature valid?", is_valid)
```
---
## ✅ 安全建议
1. **密钥保护**
- 私钥应始终加密存储(使用强密码)。
- 权限设为 `600`Linux/macOS防止他人读取。
2. **签名算法选择**
- 推荐使用 `PSS` 填充替代 `PKCS1v15` 以获得更强的安全性。
- 示例修改:
```python
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
)
```
3. **密钥长度**
- 至少使用 2048 位,推荐 3072 或 4096 以应对未来威胁。
4. **避免直接加密大数据**
- RSA 不适合直接加密大量数据。
- 应结合 AES 等对称加密使用“混合加密”方案。
---
## 📚 参考资料
- [cryptography 官方文档](https://cryptography.io/en/latest/)
- [OpenSSH Key Format](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key)
- RFC 8017 — PKCS #1 v2.2
- NIST FIPS 186-4 — Digital Signature Standard (DSS)
---
## 🧾 版本信息
- **语言**: Python 3.6+
- **库版本要求**: `cryptography >= 3.0`
- **许可证**: MIT示例代码实际请根据项目授权
---
> ✅ 本文档最后更新2025年4月5日
> 作者AI Assistant
> 用途开发参考、API 文档、安全实践指南