C# 在导出到c中的p12之前,将私钥添加到X509证书#
我试图以编程方式将证书导出到具有私钥的p12,而不必首先将其导入证书存储 我尝试复制的流程如下所示:C# 在导出到c中的p12之前,将私钥添加到X509证书#,c#,ios,x509certificate,C#,Ios,X509certificate,我试图以编程方式将证书导出到具有私钥的p12,而不必首先将其导入证书存储 我尝试复制的流程如下所示: 在Mac上,使用密钥链创建证书签名请求 使用此选项可使用为iOS应用创建配置证书 苹果的门户网站 然后我下载苹果公司新的.cer文件 由我的csr生成 通常,您接下来要做的是双击.cer并单击它 将导入到KeyChain Access中,并作为一部分显示 创建的原始私钥的 然后右键单击新证书条目并导出 这是一个.p12 我需要复制c#中的最后两个步骤。我有一个来自苹果的.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,如下所示:
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()),我现在很困惑,如果它是随机的,解密是如何发生的
谢谢。首先,我要感谢上面提到的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,它可以与苹果的推送通知系统一起工作。ios?还是macOS。净核心还是单核?你做了什么来生产你认为不匹配的PFX?(请注意,PFX中有一个随机IV,因此在相同内容上两代PFX仍会产生不同的结果)。这是一个使用.NET生成PFX的iOS应用程序。我不明白你关于随机性的最后一点。当我使用.NET生成PFX时,每次都返回相同的字符串.odd。我刚刚检查了Windows Server 2012 R2上的.NET Framework 4.6.2,在同一个对象上调用X509Certificate2.Export(X509ContentType.Pkcs12,“”)两次会产生不同的输出(相同的长度,不同的值),无论是公共+私有对证书还是仅公共对证书。是的,你是对的。快速测试中的最后58个字符不同,但其余字符完全相同。两者的长度也都是2344。当我将其与我生成的手动版本进行比较时,它的长度是4460,所以我肯定没有做什么。很高兴知道它们不会完全一样,但我希望长度匹配。