我认为这将是直截了当的,但显然它不是。我有一个证书安装了一个私钥,可导出的,我想以编程方式导出与公钥只。换句话说,当我通过certmgr导出并导出到.CER时,我想要一个相当于选择“不导出私钥”的结果。导出X.509证书无私钥
似乎所有的X509Certificate2.Export方法都会将私钥(如果存在的话)导出为PKCS#12,这与我想要的相反。
是否有任何方式使用C#来完成此任务,还是我需要开始深入CAPICOM?
我认为这将是直截了当的,但显然它不是。我有一个证书安装了一个私钥,可导出的,我想以编程方式导出与公钥只。换句话说,当我通过certmgr导出并导出到.CER时,我想要一个相当于选择“不导出私钥”的结果。导出X.509证书无私钥
似乎所有的X509Certificate2.Export方法都会将私钥(如果存在的话)导出为PKCS#12,这与我想要的相反。
是否有任何方式使用C#来完成此任务,还是我需要开始深入CAPICOM?
对于任何可能遇到此问题的人,我都明白了。如果您指定X509ContentType.Cert
作为X509Certificate.Export
的第一个(也是唯一)参数,它只会导出公钥。另一方面,指定X509ContentType.Pfx
包含私钥(如果存在)。
上周我可以发誓我看到了不同的行为,但是我在测试时必须已经安装了私钥。当我今天删除该证书并从头开始重新开始时,我发现导出的证书中没有私钥。
有一个OpenSSL .NET wrapper你可能会觉得有用。
我发现下面的计划自己放心,证书的RawData
属性包含只有公钥有帮助(MSDN不清楚这个),以及预期上述关于X509ContentType.Cert
与X509ContentType.Pfx
作品答案:
using System;
using System.Linq;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
class Program
{
static void Main(string[] args)
{
var certPath = @"C:\blah\somecert.pfx";
var certPassword = "somepassword";
var orig = new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.Exportable);
Console.WriteLine("Orig : RawData.Length = {0}, HasPrivateKey = {1}", orig.RawData.Length, orig.HasPrivateKey);
var certBytes = orig.Export(X509ContentType.Cert);
var certA = new X509Certificate2(certBytes);
Console.WriteLine("cert A : RawData.Length = {0}, HasPrivateKey = {1}, certBytes.Length = {2}", certA.RawData.Length, certA.HasPrivateKey, certBytes.Length);
// NOTE that this the only place the byte count differs from the others
certBytes = orig.Export(X509ContentType.Pfx);
var certB = new X509Certificate2(certBytes);
Console.WriteLine("cert B : RawData.Length = {0}, HasPrivateKey = {1}, certBytes.Length = {2}", certB.RawData.Length, certB.HasPrivateKey, certBytes.Length);
var keyIdentifier = (new X509SecurityToken(orig)).CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>();
certBytes = keyIdentifier.GetX509RawData();
var certC = new X509Certificate2(certBytes);
Console.WriteLine("cert C : RawData.Length = {0}, HasPrivateKey = {1}, certBytes.Length = {2}", certC.RawData.Length, certC.HasPrivateKey, certBytes.Length);
Console.WriteLine("RawData equals original RawData: {0}", certC.RawData.SequenceEqual(orig.RawData));
Console.ReadLine();
}
}
它输出以下:
Orig : RawData.Length = 1337, HasPrivateKey = True cert A : RawData.Length = 1337, HasPrivateKey = False, certBytes.Length = 1337 cert B : RawData.Length = 1337, HasPrivateKey = True, certBytes.Length = 3187 cert C : RawData.Length = 1337, HasPrivateKey = False, certBytes.Length = 1337 RawData equals original RawData: True
你知道,如果有只导出私钥不整证书的方式?我必须摆脱私钥为字节数组,我不找到任何方法来做到这一点.... – RRR 2011-10-24 08:34:02