如何使用.Net中的PKCS#1 v1.5对数据进行编码

时间:2011-01-14 15:43:01

标签: .net compact-framework cryptography rsa smartcard

我正在尝试在符合PIV的智能卡上执行有效卡身份验证。有关详细信息,请参阅this document的附录A.2。

我拥有相关X.509证书的公钥。我需要向卡发送一些随机数据,它会用私钥签名,然后我需要用公钥验证签名。

我选择的文档中的示例指出,他们发送给签名的数据是“根据PKCS#1 v1.5签名填充方案编码的”。我如何编码我的随机数据?我认为填充数据是RSA签名过程的一部分。

// 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?

2 个答案:

答案 0 :(得分:2)

第9.2节 - this document的EMSA-PKCS1-v1_5描述了编码方法。

我找不到.NET库为我做的任何事情,所以我手动完成,因为它很容易。

像我在原始代码示例中那样散列您的数据。

  1. 将散列数据编码为DigestInfo类型的ASN.1值 - 引用文档实际上提供了所需的字节数组,因此您无需弄清楚。我使用SHA1,所以我只需将以下字节数组插入到索引0处的散列数据字节数组中:(0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14

  2. PKCS#1 v1.5编码的字节数组是{0x00,0x01,PS,0x00,T},其中T是第一步的DigestInfo字节数组,PS是0xFF的字节数组。阵列PS的长度取决于你。在我的情况下,这个数组将由一个RSA-2048私钥签名,所以数组需要长度为0x100,所以我让PS足够长到达到那个目标。

  3. 将编码的字节数组发送到智能卡进行签名。智能卡将使用私钥执行实际的RSA操作并返回结果。 .NET VerifyData函数返回true。

答案 1 :(得分:2)

使用.NET加密功能执行此操作的“正确”方法是实现您自己的System.Security.Cryptography.RSA实现。 DecryptValue - 方法应该调用智能卡“原始”RSA私钥加密方法。另外,请记住覆盖KeySize属性。

然后,您可以使用RSAPKCS1SignatureFormatter填充数据并拨打智能卡。