我在pem文件中具有以下格式的ASN.1编码的RSA私钥:
-----BEGIN RSA PRIVATE KEY-----
base64 encoded pkcs8 key
-----END RSA PRIVATE KEY-----
现在,要将其导入到我的RSACng
对象中,我需要遵循以下步骤:
读取文件并提取编码的密钥
将base64
转换为字节以获取pkcs8密钥的byte[]
将ASN.1(DER)中的byte[]
解码为关键信息(模量,指数等)
将这些参数加载到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格式
答案 0 :(得分:2)
- 为什么CngKeyBlobFormat.Pkcs8PrivateBlob不允许您将PKCS8 byte []键自动导入到RSACng对象中?
因为BEGIN RSA PRIVATE KEY
表示PKCS#1 RSAPrivateKey
,而不是PKCS#8 PrivateKeyInfo
。 PKCS#8非加密私钥将说BEGIN PRIVATE KEY
。
RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)
的ASN.1编码格式是什么?
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
等等。