如何在 .Net 中使用 PKCS #1 v1.5 编码数据

发布于 2024-10-12 01:28:21 字数 985 浏览 6 评论 0原文

我正在尝试在符合 PIV 的智能卡上执行主动卡身份验证。请参阅 此文档了解更多详细信息。

我有来自关联 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?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一身骄傲 2024-10-19 01:28:21

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

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

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.

拥抱没勇气 2024-10-19 01:28:21

本文档的第 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。

Section 9.2 - EMSA-PKCS1-v1_5 of this document describes the encoding method.

I couldn't find anything exposed by the .NET library to do this for me, so I did it manually, since it's pretty easy.

Hash your data as I did in my original code example.

  1. Encode hashed data into ASN.1 value of type DigestInfo - the cited document actually provides the byte arrays needed for this so you don't have to figure it out. I used SHA1, so I just had to insert the following byte array into my hashed data byte array at index 0: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14

  2. The PKCS #1 v1.5 encoded byte array is {0x00, 0x01, PS, 0x00, T}, where T is the DigestInfo byte array from the first step and PS is a byte array of 0xFF's. The length of array PS is up to you. In my case, this array was going to be signed by an RSA-2048 private key, so the array needed to be length 0x100, so I made PS long enough to reach that goal.

Send the encoded byte array to the smart card to sign. The smart card will perform the actual RSA operation with the private key and return the result. The .NET VerifyData function returns true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文