充气城堡 C# - PrivateKeyFactory.CreateKey 'Unknown object in GetInstance'

Bouncy Castle C# - PrivateKeyFactory.CreateKey 'Unknown object in GetInstance'

我有一个处理解密的示例 C# 脚本。通过使用示例提供的密钥,代码可以正常工作:

public static string DecryptByPrivateKey(string s, string key)
        {
            s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());

            engine.Init(false, GetPrivateKeyParameter(key));
            byte[] byteData = Convert.FromBase64String(s);
            var resultData = engine.ProcessBlock(byteData, 0, byteData.Length);
            return CommonHelper.EncodeBase64(resultData);
        }

private static AsymmetricKeyParameter GetPrivateKeyParameter(string s)
        {
            s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            byte[] privateInfoByte = Convert.FromBase64String(s);            
            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
            return priKey;
        }

但是,当使用我们自己的私钥时,上面的函数会在PrivateKeyFactory.CreateKey()处抛出异常:

System.ArgumentException: 'Unknown object in GetInstance: Org.BouncyCastle.Asn1.DerInteger Parameter name: obj'

我们的 public/private 密钥字符串是在 windows 上使用 openssl 使用命令行生成的:

openssl pkcs12 -in cert.pfx -nocerts -nodes -out cert.key
openssl rsa -in cert.key -out cert_private.key
openssl rsa -in cert.key -pubout -out cert_public.key

密钥字符串为base64格式。示例私钥有 1624 个字符,而我们的私钥只有 1592 个字符。

在Visual Studio 调试模式下,我检查了参数privateInfoByte 是一个“byte[1192]”。我不知道这个错误。

我不确定我的密钥字符串的格式是否正确。我该如何验证?谢谢。

根据文档,PrivateKeyFactory.CreateKey() 需要 PKCS#8 格式的私钥。但是,cert_private.key 具有 PKCS#1 格式,因此不兼容。

另一方面,

cert.key 包含 PKCS#8 格式的私钥,可以从中提取。或者,可以使用 OpenSSL 将 PKCS#1 格式的密钥转换为 PKCS#8 格式的密钥,请参阅 openssl pkcs8:

openssl pkcs8 -topk8 -nocrypt -in <pkcs#1 key file> -out <pkcs#8 key file>

cert_private.keycert.key 包含由页眉、页脚和 Base64 编码组成的 PEM 编码密钥DER 编码密钥的数量。
PrivateKeyFactory.CreateKey() 需要一个 DER 编码密钥,即从 PEM 编码密钥确定,例如从 cert.key 开始,页眉、页脚和换行符将被删除,其余部分必须进行 Base64 解码(这似乎已在您的代码中考虑)。
PEM 编码的 PKCS#8 密钥的 Header/footer 是 -----BEGIN PRIVATE KEY-----/-----END PRIVATE KEY-----,PEM 编码的 PKCS#1 密钥的 -----BEGIN RSA PRIVATE KEY----- / -----END RSA PRIVATE KEY-----.


编辑:

语句 openssl pkcs12 -out... -in... 解析 PKCS#12 文件并将包含的证书和私钥 PEM 编码写入文件。 -nocerts 导致不写入包含的证书,-nodes 导致不加密私钥(即您的语句仅导出未加密的 PEM 编码私钥)。导出私钥的格式未明确指定,但可以使用 header/footer 或 ASN.1 解析器轻松识别为 PKCS#8。

语句openssl rsa -in... -out...最终将PKCS#8格式的密钥导出为PKCS#1格式的密钥(PEM编码)。因此,要获得所需的 PKCS#8 格式密钥,您可以选择第一次使用直接从 PKCS#12 文件(参见上一节)导出的 PKCS#8 格式密钥,或者第二次将 PKCS#1 格式密钥转换回 PKCS #8 格式化密钥。

因此:是的,cert.pfx是PKCS#12格式的文件,是的,cert_private.key 是 PKCS#1 格式的密钥,与 PrivateKeyFactory.CreateKey() 不兼容,需要 PKCS#8 格式的密钥。