智能卡 CMS 解密

Smartcard CMS Decrypt

我正在使用 Bouncycastle 来管理我的项目的加密功能。 我设法使用 CMS 进行加密和解密,其中两个密钥都存储在我的文件系统中(.cert.p12)。

这是我实际使用的两个函数:

private static byte[] CmsEncrypt(byte[] message)
{
    var envelopGenerator = new CmsEnvelopedDataGenerator();
    var certificateStream = new FileStream("Test.cer", FileMode.Open, FileAccess.Read);
    var cert = new X509CertificateParser().ReadCertificate(certificateStream);
    envelopGenerator.AddKeyTransRecipient(cert);
    return
        envelopGenerator.Generate(new CmsProcessableByteArray(message), CmsEnvelopedGenerator.DesEde3Cbc)
            .GetEncoded();
}

private static byte[] CmsDecrypt(byte[] encrypted, AsymmetricKeyParameter key, X509Certificate cert)
{
    return new CmsEnvelopedData(encrypted).GetRecipientInfos().GetFirstRecipient(new RecipientID()
    {
        SerialNumber = cert.SerialNumber,
        Issuer = cert.IssuerDN
    }).GetContent(key);
}

现在我必须向前迈出一步,私钥必须在智能卡上,但我真的不知道在这种情况下使用 CMS

我可以初始化卡并解密一条简单的消息(使用标准 pkcs11,我找到了一个很好的 c# 包装器)但我找不到任何线索如何做 CMS 智能卡解密

A​​FAIK BouncyCastleSharp 开箱即用,仅使用可以暴露在主机内存中的加密密钥。但是,一定不要忘记 Bouncy Castle C# 是一个通用密码库,如果您愿意在 较低级别 APIs 上做一些额外的工作,您也可以使用它使用无法在主机内存中公开的密钥。此类密钥通常存储在专门的加密硬件中,即智能卡、HSM、TPM,通常只能通过专门的加密 API 访问和使用,例如 MS CryptoAPI(仅限 Windows)and/or PKCS#11 API(多平台)。

我创建了一个示例应用程序 - Pkcs7SignatureGenerator - for CMS signature creation with Pkcs11Interop (which I am author of) and Bouncy Castle 库。在此应用程序中,Pkcs11Interop 库通过 PKCS#11 API 使用存储在硬件设备中的私钥执行签名操作,Bouncy Castle 库负责构建 CMS (PKCS#7) 签名结构。

在您的情况下,您需要使用 BouncyCastle 库(低级 APIs)来解析 CMS 结构,然后使用 PKCS#11 库进行低级解密。这种方法需要您编写更多代码并对 CMS 有更深入的了解,但这当然可以做到。

顺便说一句,几个月前我正在评估更紧密地集成 Pkcs11Interop 和 BouncyCastle 库的可用选项,但我发现 BouncyCastle 键 material 处理 API 不提供所需的抽象级别因此,这种集成需要对库进行重大重写。这将破坏其向后兼容性,并且 IMO 不会轻易被上游开发人员接受。所以我决定不再继续了。

希望对您有所帮助。