充气城堡 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.key 和 cert.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 格式的密钥。
我有一个处理解密的示例 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.key 和 cert.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 格式的密钥。