创建RSAParamaters公共+私钥对象 [英] Create a RSAParamaters Object from public+private key

查看:219
本文介绍了创建RSAParamaters公共+私钥对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要建立一个RSAParameters在.NET对象使用私钥和公钥(.KEY和.CER文件)。是否有可能做到这一点。NET中无需使用第三方软件?如果是这样,我应该在哪里寻找。

I need to create a RSAParameters object in .Net using a private and public key (.key and .cer file). Is it possible to do this in .Net without the use of third party software? If so, where should I be looking.

我最终还是需要从该对象中提取的指数,模量,D,P,Q,DP,DQ,InverseQ以创造一个密钥块的cryptoServer。

I ultimately need to extract the Exponent, Modulus, D, P, Q, DP, DQ, InverseQ from this object in order to create a keyblob for a cryptoServer.

谢谢!

推荐答案

键和.CER文件扩展名是没有办法的关键是如何连接codeD明确的规范。然而,这是合理的,所述的.cer文件是X.509证书,它包含(除其他许多东西)的公开密钥;因此,您可能需要使用 X509证书 X509Certificate2 类(在 System.Security程序.Cryptography.X509Certificates 命名空间)脱code证书并提取公共密匙。

".key" and ".cer" file extensions are in no way an unambiguous specification of how the keys are encoded. However, it is plausible that the ".cer" file is an X.509 certificate, which contains (among many other things) the public key; hence, you may want to use the X509Certificate and X509Certificate2 classes (in the System.Security.Cryptography.X509Certificates namespace) to decode the certificate and extract the public key.

不过,你需要的私钥,而不是公共密钥。该<一href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.aspx"相对=nofollow>上X509Certificate2 MSDN文档还是比较混乱的,因为它使用的术语证书来指定无论是公共部分(你有你的.CER文件)或者公众的工会和私处,作为一个单一的文件。

However, you need the private key, not the public key. The MSDN documentation on X509Certificate2 is quite confusing because it uses the term "certificate" to designate either the public part (what you have in your ".cer" file) or the union of the public and private part, as a single file (under the format which MSDN describes as "PKCS7 (Authenticode)").

这是连接codeD RSA私钥通常遵循 PKCS描述的格式#1 ,这是不复杂,但仍然依赖于 ASN.1 ,其使用需要一点照顾。有时候,这样的RSA密钥被包装成一个更大的结构,还指定密钥类型(即关键是为RSA);看到 PKCS#8 了解详细信息。另外,无论是一种关键的编码通常$ psented PEM格式p $:这是的Base64 的有头( ----- BEGIN RSA私钥----- )和页脚。当然,的的私钥可以是任何格式(以下简称.KEY扩展而不是过于资料)。可选,既PKCS#8和PEM可对称加密(使用密码派生密钥)。也有 PKCS#12 的格式,其可以被看作是一个对于证书和私钥,围绕previous格式包装的集合存档格式; PKCS#12包括加密许多层,并在PFX(或证书文件,它不断被混淆)的名字已在微软的世界。

An encoded RSA private key usually follows the format described in PKCS#1, which is not complex, but still relies on ASN.1, whose usage requires a bit of care. Sometimes, such RSA keys are wrapped into a bigger structure which also specifies the key type (i.e. that the key is for RSA); see PKCS#8 for details. Also, both kind of key encodings are commonly presented in PEM format: that's Base64 with a header (-----BEGIN RSA PRIVATE KEY-----) and a footer. Of course, your private key could be in any format (the ".key" extension is not overly informative). Optionally, both PKCS#8 and PEM can be symmetrically encrypted (with a password-derived key). There is also the PKCS#12 format, which can be viewed as an archive format for a collection of certificates and private keys, wrapping around the previous formats; PKCS#12 includes many layers of encryption, and is known in the Microsoft world under the name of "PFX" (or "certificate file", which keeps on being confusing).

解码所有这些格式是可能有点code,但在这一点上,建议使用的已经做了,而不是滚动您自己这样的工作,一个图书馆。 充气城堡是通常的嫌疑人的工作。

Decoding all those formats is possible with a bit of code, but at that point it is recommended to use a library which already does such work, instead of rolling your own. Bouncy Castle is the usual suspect for that job.

借助 OpenSSL的命令行工具可以帮助你转换一些密钥和证书格式之间。

The OpenSSL command-line tool can help you convert between some key and certificate formats.

编辑::如果你的私钥是PKCS#8 DER格式,是的没有的受密码保护(PKCS#8可以做到这一点),那么你可以去$ C C $它用比较简单的code。 DER是用于转化的结构化数据转换成一个字节序列的一组规则。数据元是连接codeD作为三个连续的部分:

if your private key is in PKCS#8 DER format and is not protected by a password (PKCS#8 can do that), then you can decode it with relatively simple code. DER is a set of rules for transforming structured data into a sequence of bytes. A data element is encoded as three successive parts:

  • 标记它告诉什么样的价值是
  • 长度其中EN codeS字节的第三部分数量
  • 一个这是所指定的标签PTED间$ P $
  • a tag which tells what kind of value it is
  • a length which encodes the number of bytes in the third part
  • a value which is to be interpreted as specified by the tag

故名TLV(如标签,长度,值)。一些元素本身结构包含子元素,在这种情况下,该值由在子元素的编码,每个都有其自己的标签,长度和值。

hence the name "TLV" (as "Tag, Length, Value"). Some elements are themselves structures containing sub-elements, in which case the value consists in the concatenation of the encodings of the sub-elements, each with its own tag, length and value.

一个标签通常是单字节;对于PKCS#8 RSA密钥,你有兴趣标签为0x30(对于序,即与子元素的元素),0X02(整数:一个整数值)和0x04访问(OCTET STRING:一个blob)

A tag is usually a single byte; for PKCS#8 and RSA keys, you are interested in tags 0x30 (for 'SEQUENCE', i.e. an element with sub-elements), 0x02 ('INTEGER': an integer value) and 0x04 ('OCTET STRING': a blob).

一个长度为EN codeD的任一:

A length is encoded as either of:

  • 值一个字节的 N 的介于0和127(含):本恩codeS长度的 N 的;
  • 的值的字节的 N 的等于或大于129,其次是完全相同的正128 的字节,连接code以big-endian格式的长度。举例来说,324的长度将是连接codeD为三个字节:为0x82为0x01 0x44。此内容:为0x82为128 + 2,所以我一定要读两个额外的字节;长度为256 * 0×01 + 0x44 = 324
  • a single byte of value n between 0 and 127 (inclusive): this encodes the length n;
  • a byte of value n equal to or greater than 129, followed by exactly n-128 bytes which encode the length in big-endian format. For instance, a length of 324 will be encoded as three bytes: 0x82 0x01 0x44. This reads as: "0x82 is 128+2, hence I must read two extra bytes; the length is 256*0x01+0x44 = 324".

有关整数,该值应为PTED有符号,大端约定跨$ P $(第一个字节是最显著,以及第一个字节的最高位指定整数符号;对于RSA,所有值都正,因此,第一个字节为0至127的值)。需要注意的是 System.Numerics.BigInteger ,在.NET 4.0中,有一个构造函数,可以去codeA一堆字节,但希望他们在小端约定,不是big-endian的,所以你就必须扭转字节的顺序。

For an INTEGER, the value shall be interpreted with signed, big-endian convention (first byte is most significant, and high-order bit of the first byte specifies the integer sign; for RSA, all values are positive, so the first byte shall have a value between 0 and 127). Note that System.Numerics.BigInteger, in .NET 4.0, has a constructor which can decode a bunch of bytes, but it expects them in little-endian convention, not big-endian, so you would have to reverse the order of the bytes.

的PKCS#8的结构是:

The structure of PKCS#8 is:

PrivateKeyInfo ::= SEQUENCE {
        version              Version,
        privateKeyAlgorithm  AlgorithmIdentifier,
        privateKey           OCTET STRING,
        attributes           [0] Attributes OPTIONAL
}

Version ::= INTEGER { v1(0) }

这是ASN.1符号。什么是必须在这里可以理解的是,对象是一个序列元素:它是连接codeD作为序列标签(为0x30),然后是长度( N 的),那么一个值( ñ的字节,完全一致)。该值,则在于连接coded元素,每个TLV格式继承。第一个元素是一个整数,应该有数值0正常情况下(零EN codeS为0×02 0×01 0×00)下。第二个元素是一个为AlgorithmIdentifier ,这是我做的不是这里详细;它实际上是一个序列和它所标识的密钥类型(在这里,就应该说:这是一个RSA密钥)​​;只是读取标签(应为0x30),然后是长度,并跳过值。第三个要素是字节串:一个0x04访问标签,那么长的 M 的,和 M 的字节的值。这就是我们感兴趣的是价值,这是八位字节字符串的内容,应当提取。我们将取消$ C C $它在未来的一段。在 PrivateKeyInfo进行序列的第四个元素是可选的(可能不存在一样,并且通常不会),可用于连接code各种扩展这个格式。

That's ASN.1 notation. What must be understood here is that the object is a SEQUENCE element: it is encoded as a SEQUENCE tag (0x30), then a length (n), then a value (n bytes, exactly). The value then consists in a succession of encoded elements, each in TLV format. First element is an INTEGER, which should have numerical value 0 under normal conditions (a zero encodes as '0x02 0x01 0x00'). Second element is an AlgorithmIdentifier, which I do not detail here; it is actually a SEQUENCE and it identifies the key type (here, it should say "this is a RSA key"); just read the tag (should be 0x30), then the length, and skip the value. Third element is an OCTET STRING: a 0x04 tag, then a length m, and a value of m bytes. That's what we are interested in. That value, which is the contents of the OCTET STRING, should be extracted; we will decode it in the next paragraph. The fourth element of the PrivateKeyInfo SEQUENCE is optional (it may not be there at all, and usually will not) and can be used to encode various extensions to this format.

假设你已经提取八位字节字符串的内容。这是一个字节序列,这实际上是一个结构的DER编码,这在ASN.1,看起来是这样的:

Suppose that you have extracted the contents of the OCTET STRING. This is a sequence of bytes, which is actually the DER encoding of a structure which, in ASN.1, looks like this:

RSAPrivateKey ::= SEQUENCE {
        version            INTEGER,
        modulus            INTEGER,  -- n
        publicExponent     INTEGER,  -- e
        privateExponent    INTEGER,  -- d
        prime1             INTEGER,  -- p
        prime2             INTEGER,  -- q
        exponent1          INTEGER,  -- d mod (p-1)
        exponent2          INTEGER,  -- d mod (q-1)
        coefficient        INTEGER,  -- (inverse of q) mod p
        otherPrimeInfos    OtherPrimeInfos OPTIONAL
                -- otherPrimeInfos must be absent if version is two-prime,
                -- present if version is multi-prime.
}

所以八位字节字符串的内容应该以一个为0x30(SEQUENCE的标签),然后是长度(研究的),那么研究的字节。这些的研究的字节是九整数的编码。第一INTEGER应为0;如果不是,那么RSA密钥已超过两个素的因素,而你注定。八个随后的整数是您正在寻找的整数; Ç他们只是去$ C $,和你做。在最后一个字段( otherPrimeInfos )是可选的,并且应该是不存在,如果你的RSA密钥是一个正常的RSA密钥(带有两个素因数,而不是三个或更多个)。

So the contents of the OCTET STRING should begin with a 0x30 (tag of SEQUENCE), then a length (r), then r bytes. Those r bytes are the encodings of nine INTEGERs. The first INTEGER should be 0; if it is not, then the RSA key has more than two prime factors, and you are doomed. The eight subsequent INTEGERs are the integers you are looking for; just decode them, and you are done. The last field (otherPrimeInfos) is optional and should be absent if your RSA key is a "normal" RSA key (with two prime factors, not three or more).

这篇关于创建RSAParamaters公共+私钥对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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