KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11
GitHub: KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11
面向 .NET 的 PKCS#11 v3.2 托管封装库,提供默认安全的硬件密钥操作接口,屏蔽托管/非托管边界复杂性并阻止不安全加密机制的误用。
Stars: 0 | Forks: 0
# KerckhoffsLabs.Security.Cryptography.Pkcs11
**现代、默认安全的 PKCS#11 v3.2 .NET 互操作库。**
[](https://www.nuget.org/packages/KerckhoffsLabs.Security.Cryptography.Pkcs11)
[](https://kerckhoffslabs.github.io/KerckhoffsLabs.Security.Cryptography.Pkcs11/)
[](https://github.com/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11/blob/main/LICENSE)
[](https://dotnet.microsoft.com/download/dotnet/10.0)
[](https://codecov.io/gh/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11)
[](https://sonarcloud.io/summary/new_code?id=KerckhoffsLabs_KerckhoffsLabs.Security.Cryptography.Pkcs11)
## 概述
PKCS#11 (Cryptoki) 是用于与 HSM、智能卡和软件 token 通信的标准 C API。在 .NET 中使用它意味着要在托管/非托管边界之间编组句柄、机制结构体以及固定宽度的 `CK_ULONG` 值——在这里,错误的结构体布局会导致无声的内存损坏,而错误的默认设置则会造成在被利用之前无人察觉的生产漏洞。
该库将原生 PKCS#11 模块封装在一个难以误用的、符合 .NET 惯用的接口中。
- **默认安全** —— 不安全的机制(未经身份验证的加密模式、损坏的哈希、PKCS#1 v1.5 加密、低于 128 位的曲线)在任何调用到达 token 之前就会被拒绝,并且必须显式开启。在无法设置运行时限制的地方,编译时分析器会对此发出警告。
- **PKCS#11 v3.2,向后兼容** —— 在 v2.40、v3.0、v3.1 和 v3.2 模块之上提供统一的托管 API;系统会自动协商正确的调用约定,并且仅支持 v3.2 的调用在较旧的 token 上也能平滑降级。
- **抗量子准备** —— 包含 ML-KEM (FIPS 203)、ML-DSA (FIPS 204) 和 SLH-DSA (FIPS 205),以及 RSA、ECDSA、EdDSA 和 AEAD 套件。
- **BCL 风格的适配器** —— `RSAPkcs11 : RSA`、`ECDsaPkcs11 : ECDsa`、`AesGcmPkcs11`、`MLKemPkcs11` 及其同类组件可直接嵌入已针对 `System.Security.Cryptography` 编写的代码中。
- **驻留在 Token 上的密钥** —— 私有密钥默认保持不可提取状态,且操作在 token 上运行;除非您经过深思熟虑,否则绝不采取其他方式。
- **边界安全** —— 基于 `SafeHandle` 的会话和对象、确定性的资源释放、清零的机密缓冲区,以及在所有平台上都正确的 `CK_ULONG` 宽度(在 64 位 Windows 上为 4 字节,在 64 位 Unix 上为 8 字节)。兼容 NativeAOT 和裁剪。
## 安装说明
```
dotnet add package KerckhoffsLabs.Security.Cryptography.Pkcs11
```
要求 .NET 10.0 或更高版本,以及适用于您 token 的 PKCS#11 v2.40+ 模块(例如您的 HSM 供应商的库,或用于开发的 [SoftHSM2](https://github.com/opendnssec/SoftHSMv2))。
## 快速开始
加载模块,登录到 token,生成密钥对并进行签名 —— 完整流程:
```
using System.Security.Cryptography;
using System.Text;
using KerckhoffsLabs.Security.Cryptography.Pkcs11;
using KerckhoffsLabs.Security.Cryptography.Pkcs11.Algorithms;
using KerckhoffsLabs.Security.Cryptography.Pkcs11.Common;
// 1. Load the native module (initialization and finalization are tied to the object's lifetime).
using var library = new Pkcs11Library("/usr/lib/softhsm/libsofthsm2.so");
// 2. Open a logged-in session on a token, selected by label. The PIN is held in a pinned,
// zeroized buffer — never a string. Read it from a secret manager, not source.
using var pin = new SecurePin(Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("TOKEN_PIN")!));
using var workspace = library.OpenWorkspace(slotLabel: "my-token", CKU.CKU_USER, pin);
// 3. Generate a token-resident RSA key pair. The private key is non-extractable by default.
using var key = workspace.GenerateRsaKeyPair(modulusBits: 3072, label: "signing-key");
// 4. Sign and verify through the familiar System.Security.Cryptography shape (RSA-PSS by default).
using var rsa = new RSAPkcs11(key);
byte[] message = Encoding.UTF8.GetBytes("hello, token");
byte[] signature = rsa.SignData(message, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
bool ok = rsa.VerifyData(message, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
```
通过 `workspace.OpenKey("signing-key")` 使用标签查找现有密钥,而不是重新生成,并查看[文档](#documentation)以了解加密、包装、密钥派生和后量子机制。
## 安全模型
高级 API **默认安全**。如果某个加密操作的机制被认为是不安全的,它会在任何调用到达 token 之前就被拒绝并抛出 `InsecureOperationException`。若要为了遗留系统的互操作性而使用这些机制,您必须针对每个工作区显式开启:
```
workspace.AllowInsecure = true; // latched for the workspace lifetime, or
using (workspace.AllowInsecureScope()) { … } // scoped to a single operation (preferred)
```
该安全限制作用于机制级别且与方向无关——它对签名、验证、加密、解密、派生、摘要和密钥生成的触发方式完全相同。受限制的算法族包括未经身份验证的对称模式(ECB、CBC、CTR 等)、损坏/遗留的加密算法(DES/3DES、RC2、RC4、SEED、CAST、Blowfish、SKIPJACK)、损坏的哈希算法(MD2/MD5/SHA-1/RIPEMD)、PKCS#1 v1.5 *加密*以及原始 RSA(`CKM_RSA_PKCS`、`CKM_RSA_X_509`)和低于 128 位的 EC 曲线。如果能在编译时识别出不安全的选择,[分析器](https://kerckhoffslabs.github.io/KerckhoffsLabs.Security.Cryptography.Pkcs11/diagnostics.html)
(`KLPKCS11001`–`KLPKCS11010`)也会将其作为构建警告显示出来。
**RSA PKCS#1 v1.5 签名是一个特意的例外。** 默认允许使用强哈希的 v1.5 *签名*(`CKM_SHA256_RSA_PKCS` 及以上版本):带有强哈希的 RSASSA-PKCS1-v1_5 是 FIPS 186-5 批准的,并且由于普遍存在的互操作性需求而成为标准——例如 JWT `RS256`、TLS 1.2 `CertificateVerify`、X.509 证书链、代码签名——此外,由于该限制同样作用于验证操作,阻止它们将会破坏对第三方签名的验证。只有基于*损坏哈希*的 v1.5,以及 v1.5 *加密* / 原始 RSA(Bleichenbacher / ROBOT 攻击领域)才会受到限制。尽管如此,对于新代码,仍然建议首选 RSA-PSS。
## 文档
- [**API 参考**](https://kerckhoffslabs.github.io/KerckhoffsLabs.Security.Cryptography.Pkcs11/api/) —— 完整的生成接口。
- [**诊断**](https://kerckhoffslabs.github.io/KerckhoffsLabs.Security.Cryptography.Pkcs11/diagnostics.html) —— 过时警告和分析器诊断 ID,以及如何精确抑制它们。
## 从源码构建
该仓库通过 git 子模块引入了其测试后端(`pkcs11-mock`、SoftHSMv2、opencryptoki),因此请递归克隆:
```
git clone --recurse-submodules https://github.com/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11.git
cd KerckhoffsLabs.Security.Cryptography.Pkcs11
dotnet build src/KerckhoffsLabs.sln
```
如果您在克隆时没有包含子模块,请先运行 `git submodule update --init --recursive`。
```
dotnet test src/KerckhoffsLabs.sln
```
测试会通过 MSBuild target 自动从引入的子模块构建 `pkcs11-mock` —— 这在 Linux/macOS 上需要 `make` 和 `gcc`,而在 Windows 上需要 `pwsh` 和 MSVC 构建工具。
## 许可证
MIT —— 详见 [LICENSE](https://github.com/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11/blob/main/LICENSE)。
## 支持
Bug 报告和功能请求请提交至
[GitHub issues](https://github.com/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11/issues)。
## 关于
由 [KerckhoffsLabs](https://github.com/KerckhoffsLabs) 和贡献者构建并维护。
标签:PKCS#11, 互操作, 多人体追踪, 密码学, 开发工具库, 手动系统调用, 硬件安全模块