RSACng 和 CngKeyBlobFormat 导入导出格式
RSACng and CngKeyBlobFormat import and export formats
我在 pem 文件中有一个 ASN.1 编码的 RSA 私钥,格式如下:
-----BEGIN RSA PRIVATE KEY-----
base64 encoded pkcs8 key
-----END RSA PRIVATE KEY-----
现在,要将其导入我的 RSACng
对象,我需要执行以下步骤:
读取文件并提取编码密钥
将base64
转换为字节以获得pkcs8密钥byte[]
将 byte[]
从 ASN.1 (DER) 解码为关键信息(模数、指数等)
将这些参数加载到 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 中再次编码。
怎么这么乱?这就是为什么您无法将 ASN.1 DER 编码密钥导入 RSACng
的原因是 CngKeyBlobFormat.Pkcs8PrivateBlob
具有不同的 ASN.1 编码格式并且它不是 DER?潜在的解决方法是将原始 RSA 私钥编码为另一种 ASN.1 格式,因为这正是密钥的导出方式吗?
编辑:显然,RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)
使用对象标识符(我还不熟悉),但它似乎仍然是 DER 格式
- Why doesn't the CngKeyBlobFormat.Pkcs8PrivateBlob allow you to automatically import the PKCS8 byte[] key into the RSACng object?
因为 BEGIN RSA PRIVATE KEY
表示 PKCS#1 RSAPrivateKey
,而不是 PKCS#8 PrivateKeyInfo
。 PKCS#8 未加密的私钥会说 BEGIN PRIVATE KEY
.
- What is the ASN.1 encoding format of the
RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)
?
PKCS#8 私钥信息。 https://www.rfc-editor.org/rfc/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
RSA 密钥 PrivateKey
中的值是 PKCS#1 RSAPrivateKey
值。
Why is it such a mess? ... Object Identifiers ...
PKCS#8 PrivateKeyInfo 格式是任何类型私钥的容器。对象标识符 (OID) 告诉 reader 负载是什么东西。如果 OID 是 rsaEncryption
(1.2.840.113549.1.1.1) 那么 payload 是 RSAPrivateKey
,如果是 id-dsa
(1.2.840.10040.4.1) 那么 payload 是一个 INTEGER 表示私钥(上下文参数在 privateKeyAlgorithm.Parameters
中),如果它是 id-ecPublicKey
(1.2.840.10045.2.1)(是的“public”,'cuz names)那么有效载荷是 ECPrivateKey
,等等。
我在 pem 文件中有一个 ASN.1 编码的 RSA 私钥,格式如下:
-----BEGIN RSA PRIVATE KEY-----
base64 encoded pkcs8 key
-----END RSA PRIVATE KEY-----
现在,要将其导入我的 RSACng
对象,我需要执行以下步骤:
读取文件并提取编码密钥
将
base64
转换为字节以获得pkcs8密钥byte[]
将
byte[]
从 ASN.1 (DER) 解码为关键信息(模数、指数等)将这些参数加载到
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 中再次编码。
怎么这么乱?这就是为什么您无法将 ASN.1 DER 编码密钥导入 RSACng
的原因是 CngKeyBlobFormat.Pkcs8PrivateBlob
具有不同的 ASN.1 编码格式并且它不是 DER?潜在的解决方法是将原始 RSA 私钥编码为另一种 ASN.1 格式,因为这正是密钥的导出方式吗?
编辑:显然,RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)
使用对象标识符(我还不熟悉),但它似乎仍然是 DER 格式
- Why doesn't the CngKeyBlobFormat.Pkcs8PrivateBlob allow you to automatically import the PKCS8 byte[] key into the RSACng object?
因为 BEGIN RSA PRIVATE KEY
表示 PKCS#1 RSAPrivateKey
,而不是 PKCS#8 PrivateKeyInfo
。 PKCS#8 未加密的私钥会说 BEGIN PRIVATE KEY
.
- What is the ASN.1 encoding format of the
RSACng.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)
?
PKCS#8 私钥信息。 https://www.rfc-editor.org/rfc/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
RSA 密钥 PrivateKey
中的值是 PKCS#1 RSAPrivateKey
值。
Why is it such a mess? ... Object Identifiers ...
PKCS#8 PrivateKeyInfo 格式是任何类型私钥的容器。对象标识符 (OID) 告诉 reader 负载是什么东西。如果 OID 是 rsaEncryption
(1.2.840.113549.1.1.1) 那么 payload 是 RSAPrivateKey
,如果是 id-dsa
(1.2.840.10040.4.1) 那么 payload 是一个 INTEGER 表示私钥(上下文参数在 privateKeyAlgorithm.Parameters
中),如果它是 id-ecPublicKey
(1.2.840.10045.2.1)(是的“public”,'cuz names)那么有效载荷是 ECPrivateKey
,等等。