Files
blackbird/libcrypt/README.md
T
qing ac8f3da9df docs(libcrypt): 完整 README,覆盖 5 个类 API、构建、示例与注意事项
- 5 个类的完整 API 文档(Crypto_Basic/AES_CBC/Base64/SHA256/MyRSA)
- 架构层级图与 header-only 设计说明
- 构建/安装/链接指引(含 OpenSSL 3.x 依赖说明)
- 可运行的使用示例
- Private_Key 私有继承、链接 -lssl -lcrypto 等注意事项

fix(libcrypt): SHA256.hpp 删除重复 bytes_to_hex,改用基类版本

- 私有 static bytes_to_hex 与 Crypto_Basic::bytes_to_hex 重复,已删除
- include 路径统一为 "Crypto_Basic.hpp"(与其他三文件一致)
- 移除随之无用的 <iomanip> <sstream> 头文件

fix(libcrypt): AES_CBC.hpp 补充缺失的 #include <iomanip>
2026-07-30 12:26:15 +08:00

200 lines
7.2 KiB
Markdown
Raw 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.
# libcrypt — UniServe 加密库
C++20 轻量级加密库,基于 OpenSSL 3.x EVP API 封装。提供 AES-256-CBC 加解密、Base64 编解码、SHA-256 哈希、RSA 密钥管理与加解密/签名验证。
命名空间 `qing`,库文件 `libus_crypt.so`,头文件安装至 `/usr/include/us/`。被 `gateway` 的 Token 签发/验证和密码哈希直接依赖。
## 架构
```
qing::Crypto_Basic (基类: bytes_to_hex / hex_to_bytes / CRYPTO_CHECK)
├── AES_CBC AES-256-CBC 对称加密(随机密钥+IV / 外部密钥)
├── Base64 Base64 编解码(OpenSSL BIO 链)
├── SHA256 SHA-256 哈希与验证
└── MyRSA RSA 非对称密钥
├── Generator 密钥对生成(2048-bit,PKCS#8 PEM 输出)
├── Private_Key 私钥加载、OAEP 解密、PKCS1_v1_5/PSS 签名
└── Public_Key 公钥加载、OAEP 加密、PKCS1_v1_5/PSS 验签
```
所有加密类均使用 OpenSSL 3.x EVP 高层 API。`bytes_to_hex` / `hex_to_bytes` 在 `Crypto_Basic` 中实现(查表法),编译进 `libus_crypt.so`。加解密类为纯头文件(header-only),需链接时额外加 `-lssl -lcrypto`。
## 类与 API
### Crypto_Basic — 基类
提供两个静态工具方法和异常类型,不直接实例化。
| 成员 | 说明 |
|------|------|
| `bytes_to_hex(data)` | 字节向量 → 十六进制字符串(查表法) |
| `hex_to_bytes(hex)` | 十六进制字符串 → 字节向量(大小写兼容) |
| `CryptoExp` | 异常类,继承 `std::runtime_error` |
| `CRYPTO_CHECK(cond, msg)` | 宏,条件为 false 时抛出 `std::runtime_error` |
### AES_CBC — AES-256-CBC 对称加密
```cpp
AES_CBC aes; // 自动生成随机 32B 密钥 + 16B IV
AES_CBC aes(key_vec, iv_vec); // 使用外部密钥和 IV
std::string hex = aes.encrypt(text); // 加密,返回 hex 密文
std::string raw = aes.decrypt(hex); // 解密 hex 密文,返回原文
std::string k = aes.get_key(); // 获取密钥(hex)
std::string v = aes.get_iv(); // 获取 IV(hex)
```
加密输出为 hex 编码的密文,非原始字节。解密接受 hex 输入,返回原始字符串。
### Base64 — Base64 编解码
提供实例方法和静态工具方法两种调用方式。
| 方法 | 说明 |
|------|------|
| `encode(str)` / `encode(vec)` | 编码为 Base64 字符串 |
| `decode_to_string(b64)` | 解码为原始字符串 |
| `decode_to_bytes(b64)` | 解码为字节向量 |
| `base64_encode(str)` (static) | 静态编码工具 |
| `base64_decode_to_string(b64)` (static) | 静态解码工具 |
| `is_valid_base64(str)` (static) | 验证字符集合法性(不依赖 OpenSSL) |
编码不添加换行符(`BIO_FLAGS_BASE64_NO_NL`)。
### SHA256 — SHA-256 哈希
```cpp
SHA256 h;
std::string hex = h.hash("hello"); // 字符串 → hex 哈希
auto bytes = h.hash_bytes("hello"); // 字符串 → 字节哈希
bool ok = h.verify("hello", expected_hex); // 验证
// 静态快捷方式
std::string h = SHA256::sha256("hello");
```
### MyRSA — RSA 非对称密钥
**Generator** — 生成 2048-bit RSA 密钥对(OpenSSL 3.x `OSSL_PARAM` API)。
```cpp
MyRSA::Generator gen;
gen.save_pri_key("private.pem", "password"); // PKCS#8 + AES-256-CBC 加密
gen.save_pub_key("public.pem"); // SubjectPublicKeyInfo
std::string pem = gen.get_public_key_pem(); // 导出 PEM 字符串
```
**Private_Key** — 加载私钥(支持 PKCS#1/PKCS#8,加密或明文)。
```cpp
auto pri = MyRSA::Private_Key("private.pem", true, "password");
std::string raw = pri.Decrypt(cipher_hex); // OAEP 解密
std::string sig = pri.Sign(msg); // PSS 签名(默认)
std::string sig = pri.Sign(msg, RSASignaturePadding::PKCS1_v1_5);
```
> 私有继承自 `Crypto_Basic`,内部使用其工具方法,外部不可将 `Private_Key*` 转为 `Crypto_Basic*`。
**Public_Key** — 加载公钥。
```cpp
auto pub = MyRSA::Public_Key("public.pem");
std::string hex = pub.Encrypt(text); // OAEP 加密
bool ok = pub.Verify(msg, sig_hex); // 验签(默认 PSS)
bool ok = pub.Verify(msg, sig_hex, RSASignaturePadding::PKCS1_v1_5);
```
**签名填充模式**(`RSASignaturePadding` 枚举):
| 值 | 说明 |
|----|------|
| `PSS` | 概率签名方案(默认,更安全) |
| `PKCS1_v1_5` | 传统填充(兼容旧系统) |
## 构建与安装
**前置依赖**:OpenSSL 3.x(开发包 `libssl-dev`),g++ C++20。
```bash
# 一键构建 + 安装(需 sudo)
bash _set.sh
# 或手动
make # 编译 libus_crypt.so
make install # 安装头文件到 /usr/include/us/ + .so 到 /lib/
make clear # 清理构建产物
make uninstall # 卸载
```
使用:
```cpp
#include <us/Crypto_Basic.hpp>
#include <us/AES_CBC.hpp>
#include <us/Base64.hpp>
#include <us/SHA256.hpp>
#include <us/MyRSA.hpp>
```
链接(OpenSSL 符号在 header-only 类中,需显式链接):
```bash
g++ -std=c++20 ... -lus_crypt -lssl -lcrypto
```
## 使用示例
```cpp
#include <us/SHA256.hpp>
#include <us/Base64.hpp>
#include <us/AES_CBC.hpp>
#include <iostream>
int main() {
// SHA-256
std::string hash = qing::SHA256::sha256("hello world");
std::cout << "SHA256: " << hash << std::endl;
// Base64
std::string b64 = qing::Base64::base64_encode("hello");
std::cout << "Base64: " << b64 << std::endl;
// AES-256-CBC
qing::AES_CBC aes;
std::string cipher = aes.encrypt("secret message");
std::string plain = aes.decrypt(cipher);
std::cout << "AES decrypt: " << plain << std::endl;
return 0;
}
```
## 项目结构
```
libcrypt/
├── inc/us/
│ ├── Crypto_Basic.hpp # 基类:hex 转换 + 异常
│ ├── AES_CBC.hpp # AES-256-CBC 加解密(header-only)
│ ├── Base64.hpp # Base64 编解码(header-only)
│ ├── SHA256.hpp # SHA-256 哈希(header-only)
│ └── MyRSA.hpp # RSA 密钥/加解密/签名(header-only)
├── src/
│ └── Crypto_Basic.cpp # bytes_to_hex / hex_to_bytes 实现
├── Makefile
├── _set.sh
└── README.md
```
## 注意事项
- **OpenSSL 版本**:MyRSA 的 `Generator` 使用了 `OSSL_PARAM`、`EVP_PKEY_CTX_new_from_name` 等 OpenSSL 3.x 独占 API,无法在 OpenSSL 1.1.x 下编译。AES/Base64/SHA256 兼容 1.1.x。
- **链接要求**:`libus_crypt.so` 仅含 `bytes_to_hex` 和 `hex_to_bytes`(无 OpenSSL 调用)。所有加密类为 header-only,链接时必须添加 `-lssl -lcrypto`。
- **RSA 密钥长度**:默认 2048-bit,可在 `generate_rsa_key(size_t key_bits)` 中调整。
- **AES 密钥和 IV**:默认构造函数随机生成,每次创建 `AES_CBC` 对象产生不同的密钥对。需要长期存储密钥时使用参数化构造函数传入外部密钥。
- **hex 编码**:`bytes_to_hex` 使用查表法实现,位于 `Crypto_Basic.cpp` 中编译进 `.so`。`SHA256` 不再有私有副本。
- **`Private_Key` 私有继承**:该设计防止 `Private_Key` 被隐式转换为 `Crypto_Basic*`,是刻意为之的安全措施。
## 许可证
MIT License