RSACng和CngKeyBlobFormat导入和导出格式

时间:2018-07-26 09:04:52

标签: c# .net cryptography cng

我在pem文件中具有以下格式的ASN.1编码的RSA私钥:

-----BEGIN RSA PRIVATE KEY-----
base64 encoded pkcs8 key
-----END RSA PRIVATE KEY-----

现在,要将其导入到我的RSACng对象中,我需要遵循以下步骤:

  1. 读取文件并提取编码的密钥

  2. base64转换为字节以获取pkcs8密钥的byte[]

  3. 将ASN.1(DER)中的byte[]解码为关键信息(模量,指数等)

  4. 将这些参数加载到RSACng对象中

我有以下两个问题:

1。为什么 CngKeyBlobFormat.Pkcs8PrivateBlob 为什么不允许您自动将PKCS8 byte[] 键导入到 RSACng 对象?

例如,为什么它不能以这种方式工作:

var keyData = GetBytesFromPEM(pemstring); // Get the bytes for key that is ASN.1 DER encoded
CngKey cngKey = CngKey.Import(keyData, CngKeyBlobFormat.Pkcs8PrivateBlob);

CngKeyBlobFormat明确指定它是PKCS8私有Blob。

2。 RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob) 的ASN.1编码格式是什么?

我注意到,如果如上所述将密钥加载到RSACng中,然后使用上述代码导出相同的密钥,则会得到以不同ASN.1格式编码的BLOB,并且其中包含ASN.1 DER编码密钥。基本上,要从此导出的密钥中获取信息,我需要再次从此ASN.1格式对其进行解码,以获取存储在其中的原始密钥参数,这些原始参数由ASN.1 DER重新编码。

为什么这么乱?这就是为什么您无法将RSACng的ASN.1编码格式和DER不是ADER的ASN.1 DER编码密钥导入CngKeyBlobFormat.Pkcs8PrivateBlob的原因?那么可能的解决方法是将原始RSA私钥编码为另一种ASN.1格式,因为这正是密钥的导出方式?

编辑:显然,RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)使用对象标识符(我对此还不熟悉),但它似乎仍然是DER格式

1 个答案:

答案 0 :(得分:2)

  
      
  1. 为什么CngKeyBlobFormat.Pkcs8PrivateBlob不允许您将PKCS8 byte []键自动导入到RSACng对象中?
  2.   

因为BEGIN RSA PRIVATE KEY表示PKCS#1 RSAPrivateKey,而不是PKCS#8 PrivateKeyInfo。 PKCS#8非加密私钥将说BEGIN PRIVATE KEY

  
      
  1. RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)的ASN.1编码格式是什么?
  2.   

PKCS#8 PrivateKeyInfo。 https://tools.ietf.org/html/rfc5208#section-5

  PrivateKeyInfo ::= SEQUENCE {
    version                   Version,
    privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
    privateKey                PrivateKey,
    attributes           [0]  IMPLICIT Attributes OPTIONAL }

  Version ::= INTEGER

  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier

  PrivateKey ::= OCTET STRING

  Attributes ::= SET OF Attribute

PrivateKey中RSA密钥的值是PKCS#1 RSAPrivateKey值。

  

为什么这么乱? ...对象标识符...

PKCS#8 PrivateKeyInfo格式是任何类型的私钥的容器。对象标识符(OID)告诉读者有效负载是什么东西。如果OID为rsaEncryption(1.2.840.113549.1.1.1),则有效载荷为RSAPrivateKey;如果为id-dsa(1.2.840.10040.4.1),则有效载荷为INTEGER,表示私钥(并且上下文参数在privateKeyAlgorithm.Parameters中),如果它是id-ecPublicKey(1.2.840.10045.2.1)(是“ public”,'cuz名称),则有效负载为ECPrivateKey等等。