Smartcard CMS Decrypt

2019-03-21 17:19发布

问题:

I'm using Bouncycastle to manage the Encrypt function of my project. I managed out to use CMS for encrypt and decrypt where both key are stored in my file system (a .cert and a .p12).

These are the two function I'm actually using:

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);
}

Now I have to do a step forward, The private key must be on a smartcard but I can't really figure out to use the CMS in this scenario.

I can initialize the card and decrypt a simple message (using standard pkcs11, I found a good wrapper for c#) but I can't find any clue how to do CMS decryption with smartcard.

回答1:

AFAIK BouncyCastleSharp works out-of-the-box only with the cryptographic keys that can be exposed into the host memory. However one must not forget that Bouncy Castle C# is a general purpose cryptographic library and if you are willing to do a little extra work on lower level APIs you can use it also with the keys that cannot be exposed in the host memory. Such keys are usually stored in specialized cryptographic hardware i.e. smartcards, HSMs, TPMs and usually can be accessed and used only via a specialized cryptographic API such as MS CryptoAPI (Windows only) and/or PKCS#11 API (multiplatform).

I have created an example application - Pkcs7SignatureGenerator - for CMS signature creation with Pkcs11Interop (which I am author of) and Bouncy Castle libraries. In this application Pkcs11Interop library performs signing operation via PKCS#11 API with the private key stored in the hardware device and Bouncy Castle library is responsible for construction of a CMS (PKCS#7) signature structure.

In your case you would need to use BouncyCastle library (low level APIs) to parse CMS structure and then use PKCS#11 library for low level decryption. This approach requires you to do more coding and to have much deeper understanding of CMS but it certainly can be done.

BTW few months ago I was evaluating available options for a closer integration of Pkcs11Interop and BouncyCastle libraries but I have found out that BouncyCastle key material handling APIs do not provide required level of abstraction and therefore such integration would require major rewrite of the library. That would break its backwards compatibility and IMO would not get accepted easily by the upstream developers. So I have decided not to proceed any further.

Hope this helps.