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 互操作库。** [![NuGet](https://img.shields.io/nuget/v/KerckhoffsLabs.Security.Cryptography.Pkcs11)](https://www.nuget.org/packages/KerckhoffsLabs.Security.Cryptography.Pkcs11) [![文档](https://img.shields.io/badge/docs-online-2ea44f)](https://kerckhoffslabs.github.io/KerckhoffsLabs.Security.Cryptography.Pkcs11/) [![许可证: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11/blob/main/LICENSE) [![.NET](https://img.shields.io/badge/.NET-10.0-512BD4)](https://dotnet.microsoft.com/download/dotnet/10.0) [![codecov](https://codecov.io/gh/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11/graph/badge.svg?token=4IJFAX88L9)](https://codecov.io/gh/KerckhoffsLabs/KerckhoffsLabs.Security.Cryptography.Pkcs11) [![质量门状态](https://sonarcloud.io/api/project_badges/measure?project=KerckhoffsLabs_KerckhoffsLabs.Security.Cryptography.Pkcs11&metric=alert_status)](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, 互操作, 多人体追踪, 密码学, 开发工具库, 手动系统调用, 硬件安全模块