2

我正在尝试在符合 PIV 的智能卡上执行主动卡身份验证。有关详细信息,请参阅本文档的附录 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?
4

2 回答 2

2

本文档的第 9.2 节 - 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 足够长以达到这个目标。

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

于 2011-01-14T17:32:43.820 回答
2

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

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

于 2011-01-14T18:49:08.613 回答