我试图以编程方式将证书导出到带有私钥的p12,而不必先将其导入到证书存储区。添加私钥到X509证书,然后导出到p12在c#
我试图复制的流程如下:
- 在Mac上创建一个使用钥匙串证书签名请求。
- 使用此命令可以使用 Apple门户为iOS应用程序创建配置证书。
- 然后,我下载新的.cer文件,Apple从我的csr生成 。
- 通常情况下,您要做的是双击.cer,然后 将导入到KeyChain Access中,并与创建的原始私钥一起出现,并与 一同出现。
- 然后,您可以右键单击新证书条目并将其作为.p12导出为 。
我需要复制c#中的最后2个步骤。我有一个来自Apple的.cer,我拥有公钥和私钥,并且我需要以这种方式应用私钥,以便当我以编程方式将其导出为p12时,它与我在上面手动执行的操作相匹配。
我可以导入.CER像这样:
X509Certificate2 originalCert = new X509Certificate2(@"c:\temp\aps.cer");
//then export it like so
byte[] p12 = originalCert.Export(X509ContentType.Pkcs12, "password");
但是,当我用一个比较一下我手动创建了钥匙链的不匹配,即:
byte[] p12Bytes = File.ReadAllBytes(@"c:\temp\manual.p12");
string manual = Convert.ToBase64String(p12Bytes);
string generated = Convert.ToBase64String(p12);
Assert.IsTrue(manual == generated);//this fails
有可能的当然是我的理解如何这一切工作的问题:)
我已经尝试使用BouncyCastle库来做到这一点,但下面的代码在最后的输出没有做任何事情。
Org.BouncyCastle.X509.X509Certificate cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(originalCert);
X509CertificateEntry[] chain = new X509CertificateEntry[1];
X509CertificateEntry entry = new X509CertificateEntry(cert);
chain[0] = entry;
AsymmetricKeyEntry keyPair;
using (StreamReader reader = File.OpenText(@"c:\temp\EXPORTED PRIVATE KEY.p12"))
{
Pkcs12Store store = new Pkcs12Store(reader.BaseStream, "Password".ToCharArray());
foreach (string n in store.Aliases)
{
if (store.IsKeyEntry(n))
{
AsymmetricKeyEntry key = store.GetKey(n);
if (key.Key.IsPrivate)
{
keyPair = key;
pfx.SetKeyEntry("TEST CERT", key, chain);
break;
}
}
}
}
任何人都可以请指点我在正确的方向吗?
编辑:我做了一个更改,看起来很有前途,因为键的长度现在几乎匹配。我现在通过BouncyCastle的导出P12像这样:
看来使用随机生成的字节来执行操作(见新SecuredRandom()),我现在很困惑,如何发生解密,如果它是随机化的?
谢谢。
ios?还是macOS? .NET Core或Mono?你做了什么来生产你认为不匹配的PFX? (请注意,PFX中有一个随机IV,因此在相同内容上生成两个PFX仍会产生不同的结果)。 – bartonjs
这是一个使用.NET生成PFX的iOS应用程序。我不明白你关于随机性的最后一点。当我使用.NET生成PFX时,每次都会返回相同的字符串。 –
单数。我刚刚在Windows Server 2012 R2上使用.NET Framework 4.6.2进行了检查,并且在同一个对象上调用X509Certificate2.Export(X509ContentType.Pkcs12,“”)两次产生不同的输出(相同长度,不同值),无论它是公共+私人配对证书或公共专用证书。 – bartonjs