来自公钥的 RSA 模数和指数 [英] RSA modulus and exponent from public key

查看:69
本文介绍了来自公钥的 RSA 模数和指数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上有与 这个问题,但我无法填写已接受的答案中遗漏的明显微不足道的部分.我正在使用 Mono 在 C# 中执行此操作.

I basically have the same problem as in this question, but I'm having trouble filling in the apparently trivial parts left out from the accepted answer. I'm doing this in C# with Mono.

我有一个 CA 根证书,从中我可以得到一个持有公钥的 byte[].然后我得到一个我需要验证的不受信任的证书.据我了解,RSACryptoServiceProvider.VerifyData 应该可以解决问题,但首先我需要使用公钥中的模数和指数设置 RSAParameters.

I have a CA root certificate, and from that I can get a byte[] holding a public key. I then get an untrusted certificate I need to verify. From what I understand, RSACryptoServiceProvider.VerifyData should do the trick, but first I need to set RSAParameters with the modulus and exponent from the public key.

(以下内容重复了我在上面链接的问题中已经显而易见的一些事情.)
应该执行我需要的操作并使用我信任的根证书验证服务器证书的代码如下:

( The following repeats some things already apparent from the question I linked to above.)
The piece of code that should do what I need and validate a server's certificate with a root certificate I trust is as follows:

RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();
RSAParameters publicKeyParams = new RSAParameters();
publicKeyParams.Modulus = GetPublicKeyModulus();
publicKeyParams.Exponent = GetPublicKeyExponent();
publicKey.ImportParameters(publicKeyParams);
return publicKey.VerifyData(SignedValue(), CryptoConfig.MapNameToOID("SHA1"), Signature());

我的问题是 GetPublicKeyModulus() 和 GetPublicKeyExponent() 的内容.在接受的答案中,它们显然是微不足道的,只是评论说模数是我的公钥中第一个 TLV 的值,指数是公钥中的第二个 TLV.我不完全明白这是什么意思.

My problem is the contents of the GetPublicKeyModulus() and GetPublicKeyExponent(). In the accepted answer they are left out as apparently trivial, with just a comment saying the modulus is the value of the first TLV in my public key, and the exponent is the second TLV in the public key. I don't fully understand what that means.

byte[] GetPublicKeyExponent()
{
  // The value of the second TLV in your Public Key
}

byte[] GetPublicKeyModulus()
{
  // The value of the first TLV in your Public Key
}
byte[] SignedValue()
{
  // The first TLV in your Ceritificate
}

byte[] Signature()
{
  // The value of the third TLV in your Certificate
}

我的问题是这些第一个 TLV"/第二个 TLV"究竟是什么意思,我如何从我拥有的字节数组中获取这些值?

据我所知,TLV 代表类型-长度-值.因此,如果我猜对了,那么包含公钥的字节数组的第一位包含有关模数数据有多少位的信息.使用该信息,我应该将公钥中的该位数复制到另一个数组中,并将 RSAParameters.Modulus 设置为该值.在公钥中的模数之后是指数,我应该用它做同样的操作.但是我无法在包含的公钥数据中找到有关 TLV 的TL"部分的位数和格式的信息.

From what I understand, TLV stands for type-length-value. So if I have it correct, first bits of the byte array containing the public key have information about how many bits the modulus data is. Using that information I'm supposed to copy that amount of bits from the public key into another array, and set RSAParameters.Modulus to that value. After the modulus in the public key comes the exponent, and I should do the same operation with that. But I can't find information about in how many bits and in what format is the "TL" part of a TLV in the public key data contained.

我在别处找到的信息说模数是公钥中的前 1024 位,指数是余数,但这在字节数组之间复制数据时给了我关于大小的错误.

I found information elsewhere saying the modulus is the first 1024 bits in the public key, and the exponent is the remainder, but that gave me an error about size when copying data between the byte arrays.

目前我根据我链接的问题中接受的答案形成的代码基本上是这样的:

At the moment my code that I've been forming based on the accepted answer in the question I linked looks basically like this:

using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;

X509Certificate2 trustedRootCertificate = new X509Certificate2(X509Certificate2.CreateFromCertFile(filename));
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
.
.
public bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
  .
  .
  byte[] publicKeyBytes = trustedRootCertificate.GetPublicKey();
  byte[] modulusData = // The value of the first TLV in the Public Key??
  byte[] exponentData = // The value of the second TLV in the Public Key??

  RSAParameters publicKeyParams = new RSAParameters();
  publicKeyParams.Modulus = modulusData;
  publicKeyParams.Exponent = exponentData;
  RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();
  publicKey.ImportParameters(publicKeyParams);

  byte[] certificateData = certificate.GetRawCertData();
  byte[] signedValue = // The first TLV in the certificate??
  byte[] encryptedSignature = // The third TLV in the certificate??

  return publicKey.VerifyData(certificateData, HashAlgorithm.Create("SHA1"), encryptedSignature);
}

或者我应该在 VerifyData 调用中使用 certificateData(certificate.GetRawCertData() 的返回值)?

Or should I be using certificateData (the return value of certificate.GetRawCertData()) in the VerifyData call?

在其他地方,我发现加密签名部分是证书数据中的最后 256 位,我不确定这是否与证书中的第三个 TLV"相同.如果没有,我会做

Elsewhere I've found that the encrypted signature part is the last 256 bits in the certificateData, I'm not sure if that's the same as "the third TLV in the certificate". If not, I'd be doing

byte[] certificateData = certificate.GetRawCertData();
byte[] encryptedSignature = new byte[256];
System.Array.Copy(certificateData, certificateData.Length - 256, encryptedSignature, 0, 256);

然后使用 encryptedSignature 作为 VerifyData 调用中的最后一个参数.

and then using encryptedSignature as the last parameter in the VerifyData call.

我还尝试了简单的 TLV 业务,而不是所有这些业务

Instead of all this TLV business I've also tried simply

RSACryptoServiceProvider publicKey = trustedRootCertificate.PublicKey.Key as RSACryptoServiceProvider;

作为我在上面链接到的问题中的人,但是使用此验证数据调用然后在我认为不应该返回 false 时返回 false.应用程序从服务器获得的证书已将 trustrootCertificate 作为其根证书,我应该可以用它来做到这一点,对吗?根的公钥应该可以验证服务器的证书?

as the person in the question I linked to above, but using this the VerifyData call then returned false when I thought it shouldn't. The certificate the application gets from the server has trustedRootCertificate as its root cert, I should be able to do this with that, correct? The root's public key should be able to verify the server's cert?

很可能我从一开始就对证书验证的基本知识有误.如果情况并非如此,那么我的问题是如何获得这些值

It's very much possible I just have the very basics of certificate verification wrong from the start. If that's not the case, then my question is how do I get these values

// The value of the second TLV in your Public Key
..
// The value of the first TLV in your Public Key

来自我拥有的受信任根证书的公钥.

from the public key of the trusted root cert I have.

我还验证了从文件加载的根证书和应用程序从服务器获取的证书是通过打印他们的信息应该是什么,所以问题不至少在证书错误.我只是不知道如何正确使用它们.

I've also verified that the root certificate loaded from the file and the certificate the app gets from the server are what they're supposed to be by printing out their information, so the problem is not at least in the certificates being wrong. I just don't know how to use them correctly.

推荐答案

假设您遇到 BIT STRING 类型包含以下 Length - Value::

Lets say that you encountered with BIT STRING type containing the following Length - Value::

03(T - BIT STRING) 
82(Read next 2 Bytes for actual Length) 
01 0F(Actual Length of whole BIT STRING) 

---BIT STRING Value Starts Here---
00(First Byte Of BIT STRING specifies the number of bits left unused in the final byte of BIT STRING which in this case is 0)

30(T - SEQUENCE) 
82(Read next 2 Bytes for actual Length) 
01 0A(Actual Length of whole SEQUENCE) 

---SEQUENCE Value Starts Here---
02(T - INTEGER) 
82(Read next 2 Bytes for actual Length) 
01 01(Actual Length of whole INTEGER) 

(Value starts from here till "Actual Length of whole INTEGER above")
---INTEGER Value Starts Here---
---Exponent Starts Here---
00 A9  CA B2 A4 CC CD 20 AF 0A
7D 89 AC 87 75 F0 B4 4E  F1 DF C1 0F BF 67 61 BD
A3 64 1C DA BB F9 CA 33  AB 84 30 89 58 7E 8C DB
6B DD 36 9E 0F BF D1 EC  78 F2 77 A6 7E 6F 3C BF
93 AF 0D BA 68 F4 6C 94  CA BD 52 2D AB 48 3D F5
B6 D5 5D 5F 1B 02 9F FA  2F 6B 1E A4 F7 A3 9A A6
1A C8 02 E1 7F 4C 52 E3  0E 60 EC 40 1C 7E B9 0D
DE 3F C7 B4 DF 87 BD 5F  7A 6A 31 2E 03 99 81 13
A8 47 20 CE 31 73 0D 57  2D CD 78 34 33 95 12 99
12 B9 DE 68 2F AA E6 E3  C2 8A 8C 2A C3 8B 21 87
66 BD 83 58 57 6F 75 BF  3C AA 26 87 5D CA 10 15
3C 9F 84 EA 54 C1 0A 6E  C4 FE C5 4A DD B9 07 11
97 22 7C DB 3E 27 D1 1E  78 EC 9F 31 C9 F1 E6 22
19 DB C4 B3 47 43 9A 1A  5F A0 1E 90 E4 5E F5 EE
7C F1 7D AB 62 01 8F F5  4D 0B DE D0 22 56 A8 95
CD AE 88 76 AE EE BA 0D  F3 E4 4D D9 A0 FB 68 A0
AE 14 3B B3 87 C1 BB 
-----Exponent Ends Here----
---INTEGER Value Ends Here---


02(T - INTEGER)  
03(Actual Length cuz 8th Bit Not Set here, so this byte shows the actual length)

---INTEGER Value Starts Here---
----Mod Starts Here--- 
01 00 01
---Mod Ends Here---
---INTEGER Value Ends Here---

---SEQUENCE Value Ends Here---
---BIT STRING Value Ends Here---

您可能想阅读ASN.1 格式

这篇关于来自公钥的 RSA 模数和指数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆