Search code examples
.netcompact-frameworkcryptographyrsasmartcard

How to encode data with PKCS #1 v1.5 in .Net


I am trying to perform active card authentication on a PIV compliant smartcard. See Appendix A.2 of this document for more details.

I have the public key from the associated X.509 Certificate. I need to send the card some random data, which it will sign with its private key, then I need to verify the signature with the public key.

The example in the document I sited notes that the data they send to be signed is "encoded in accordance with the PKCS #1 v1.5 signature padding scheme". How do I encode my random data like that? I thought padding the data was part of the RSA signing process.

// Generate random data
byte[] randomData = new byte[128];
Random random = new Random();
random.NextBytes(randomData);

// Hash the random data
SHA1Managed sha1 = new SHA1Managed();
byte[] hash = sha1.ComputeHash(randomData);

// Send the hash to the Smart Card and get back signed data
byte[] signature = SendToSmartCardForSignature(hash);

// Verify the data and the signature match using the public key
RSACryptoServiceProvider rsa = smartCardCertificate.PublicKey;
bool verified = rsa.VerifyData(randomData, CryptoConfig.MapNameToOID("SHA1"), signature);

// verified is false...why?

Solution

  • The "right" way to do this using the .NET crypto-functionality is to implement your own implementation of System.Security.Cryptography.RSA. The DecryptValue-method should call the smartcards "raw" RSA private key encryption method. Also, remember to override the KeySize property.

    You can then use RSAPKCS1SignatureFormatter to pad the data and call the smartcard.