在c#中导出到p12之前,将私钥添加到X509证书中

本文关键字:私钥 X509 证书 添加 p12 之前 | 更新日期: 2023-09-27 18:01:59

我正在尝试以编程方式将证书与其私钥导出到p12,而不必先将其导入证书存储。

我试图复制的流程如下:

  1. 在Mac上使用Keychain创建证书签名请求
  2. 为iOS应用创建一个配置证书苹果的门户。
  3. 然后我下载苹果新的。cer文件
  4. 通常你要做的是双击。cer,然后它会导入到KeyChain访问和出现与和作为一个部分吗
  5. 然后您可以右键单击新的证书条目并导出

我需要在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;
                    }
                }
            }
        }
谁能给我指个正确的方向?

EDIT:我又做了一个改变,看起来很有希望,因为键的长度现在几乎匹配。我现在通过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);
            }
       }

它似乎使用随机生成的字节来执行操作(见新的securedrrandom()),我现在很困惑,解密是如何发生的,如果它是随机的?

谢谢。

在c#中导出到p12之前,将私钥添加到X509证书中

首先我要感谢bartonjs上面的帮助解决这个问题。不同的长度让我以不同的方式思考这个问题。

我上面的编辑解决了这个问题。我假设通过调用:
 pfx.SetKeyEntry("MyKey", key, chain);

它会将密钥设置到链中的证书中。相反,我必须像这样导出它们:

using (MemoryStream stream = new MemoryStream())
{
     pfx.Save(stream, "Password".ToCharArray(), new SecureRandom());//The SecureRandom must be responsible for the different strings/lengths when re-generated.
     using (BinaryReader reader = new BinaryReader(stream))
     {
         byte[] p12 = stream.ToArray();
         //then I can save this off somewhere - in my case the db.
     }
}

现在我有了一个带有证书和私钥的p12,它可以与Apple的推送通知系统一起使用。