C# X509Certificate2无法解码Xamarin.iOS上的.PFX证书
我对Xamarin和X509证书的组合存在问题 我们有一个应用程序需要使用BouncyCastle库生成一个.PFX文件。该文件在一个简单的.NET控制台应用程序中成功生成并解码,无错误,以便与AWS IoT上的MQTT message broker通信。然后我们把代码移到了Xamarin。在一些代码更改之后,我们设法让Android版本工作并与MQTT消息代理通信。但是,在iOS上运行时失败,特别是使用.PFX文件的路径和适当的密码创建新的X509Certificate2对象时,使用以下代码:C# X509Certificate2无法解码Xamarin.iOS上的.PFX证书,c#,ios,xamarin,bouncycastle,x509certificate2,C#,Ios,Xamarin,Bouncycastle,X509certificate2,我对Xamarin和X509证书的组合存在问题 我们有一个应用程序需要使用BouncyCastle库生成一个.PFX文件。该文件在一个简单的.NET控制台应用程序中成功生成并解码,无错误,以便与AWS IoT上的MQTT message broker通信。然后我们把代码移到了Xamarin。在一些代码更改之后,我们设法让Android版本工作并与MQTT消息代理通信。但是,在iOS上运行时失败,特别是使用.PFX文件的路径和适当的密码创建新的X509Certificate2对象时,使用以下代码:
X509Certificate2 clientCertPfx=新的X509Certificate2(Path.Combine(folderPath,certificatePathPfx),密码)代码>
它失败并显示错误消息:加密异常:无法解码证书
此错误仅在Xamarin.iOS版本中发生;Android构建按预期运行。我们跟踪堆栈跟踪,找到与错误消息匹配的以下内容。似乎没有正确解析/读取.PFX文件。我想知道是否有人知道是否有办法避免这个错误。这是X509Certificate2方法的Mono实现中的一个缺点吗?是否有可能BouncyCastle Pcks12Builder错误地导出了.PFX文件或其他文件
任何帮助都将不胜感激,我很高兴根据需要提供任何额外的代码
编辑1
下面是我用来生成.PFX文件的代码
var pfxStore = new Pkcs12StoreBuilder()
.SetUseDerEncoding(true)
.Build();
StreamReader reader = File.OpenText(cert_file_pem); // signed PEM certificate file
var pemReader = new PemReader(reader);
List<X509CertificateEntry> chain = new List<X509CertificateEntry>();
AsymmetricCipherKeyPair privKey = null;
object o;
while ((o = pemReader.ReadObject()) != null)
{
if (o is Org.BouncyCastle.X509.X509Certificate)
{
chain.Add(new X509CertificateEntry((Org.BouncyCastle.X509.X509Certificate)o));
}
else if (o is AsymmetricCipherKeyPair)
{
privKey = (AsymmetricCipherKeyPair)o;
}
}
if (privKey == null)
{
using (StreamReader privKeyReader = File.OpenText(key_file)) // private key file
{
privKey = (AsymmetricCipherKeyPair)new PemReader(privKeyReader).ReadObject();
}
}
pfxStore.SetKeyEntry("convert", new AsymmetricKeyEntry(privKey.Private), chain.ToArray());
MemoryStream pfxMemoryStream = new MemoryStream();
pfxStore.Save(pfxMemoryStream, thingName.ToCharArray(), new SecureRandom());
var result = Pkcs12Utilities.ConvertToDefiniteLength(pfxMemoryStream.ToArray(), password.ToCharArray());
FileStream pfxFileStream = File.Create(certificatePathPfx);
pfxFileStream.Write(result);
pfxFileStream.Close();
pfxMemoryStream.Close();
在.NET控制台应用程序中运行这段代码时,我得到以下输出:
Cert type for PFX doc (data): Cert
Cert type for PFX doc (path): Pfx
似乎X509Certificate2.GetCertContentType()
函数根据是使用文件名路径还是原始文件数据调用函数来选择不同的内容类型。如果您手动构建了PFX,则可能是以iOS无法识别的方式构建的。IIRC它需要是PFX{非加密内容{隐藏私钥},加密内容{证书},MAC存在}
。与此不同(未加密的证书、未加密的密钥、加密内容桶中的隐藏密钥、没有MAC)通常会导致macOS(可能还有iOS)无法正确读取。您好@bartonjs,谢谢您的回答。您是否有代码片段或其他我们可以使用的东西来设置这种格式的文件?目前,我们只是使用标准的BouncyCastle Pkcs12Store来创建文件。有没有一种方法可以修改store builder以允许这种格式?您有没有尝试过看看这个?有什么最新消息吗?我也有同样的错误
Cert type for PFX doc (data): Cert
Cert type for PFX doc (path): Pfx