【发布时间】:2016-08-12 05:29:36
【问题描述】:
我正在尝试使用其私钥以编程方式将证书导出到 p12,而不必先将其导入证书存储区。
我试图复制的流程如下:
- 在 Mac 上使用钥匙串创建证书签名请求。
- 使用它为 iOS 应用程序创建配置证书,使用 苹果的门户。
- 然后我下载 Apple 提供的新 .cer 文件 从我的 csr 生成。
- 通常你会做的是双击 .cer 和它 将导入 KeyChain Access 并作为一部分出现 创建的原始私钥。
- 然后您可以右键单击新的证书条目并导出 这是一个 .p12。
我需要在 c# 中复制最后两个步骤。我有一个来自 Apple 的 .cer,我有公钥和私钥,我需要以某种方式应用私钥,以便当我以编程方式将其导出为 p12 时,它与我在上面手动执行的那个匹配。
我可以像这样导入 .cer:
X509Certificate2 originalCert = new X509Certificate2(@"c:\temp\aps.cer");
//then export it like so
byte[] p12 = originalCert.Export(X509ContentType.Pkcs12, "password");
但是当我将它与我手动创建的 KeyChain 进行比较时,它不匹配,即:
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,如下所示:
using (MemoryStream stream = new MemoryStream())
{
pfx.Save(stream, "password".ToCharArray(), new SecureRandom());
byte[] p12Bytes = File.ReadAllBytes(@"c:\temp\newexported.p12");
string realp12 = Convert.ToBase64String(p12Bytes);
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] p12 = stream.ToArray();
string generated12 = Convert.ToBase64String(p12);
Assert.IsTrue(realp12.Length == generated12.Length);
}
}
它似乎使用随机生成的字节来执行操作(参见 new SecuredRandom()),我现在很困惑,如果它是随机的,解密是如何发生的?
谢谢。
【问题讨论】:
-
ios?还是 macOS? .NET Core 还是 Mono?你做了什么来制作你认为不匹配的 PFX? (请注意,PFX 中有一个随机 IV,因此相同内容的两代 PFX 仍然会产生不同的结果)。
-
这是一个使用 .NET 生成 PFX 的 iOS 应用程序。我不明白你关于随机性的最后一点。当我使用 .NET 生成 PFX 时,每次都会返回相同的字符串。
-
奇怪。我刚刚检查了 Windows Server 2012 R2 上的 .NET Framework 4.6.2,并在同一个对象上调用 X509Certificate2.Export(X509ContentType.Pkcs12, "") 两次会产生不同的输出(相同的长度,不同的值),无论它是公共的+私人对证书或仅公共证书。
-
是的,你是对的。快速测试中的最后 58 个字符不同,但其余字符完全相同。两者都是 2344 长。当我将它与我生成的手册进行比较时,它的长度为 4460,所以肯定有一些我没有做的事情是钥匙串。很高兴知道它们无论如何都不完全相同,但我希望长度匹配。
标签: c# ios x509certificate