我想这将是简单的,但显然事实并非如此。我已经安装了证书,具有私钥,导出,我想以编程方式,只有公共密钥导出。换句话说,我希望有一个结果等同于选择“不要导出私钥”,通过certmgr出口并出口到.CER时。

似乎所有的X509Certificate2.Export方法将导出私钥如果存在的话,作为PKCS#12,这是我想的正好相反。

有没有使用C#来完成这个任何方式,或者我需要开始挖成CAPICOM?

有帮助吗?

解决方案

有关谁比谁有可能在这迷迷糊糊中,我想通了。如果指定X509ContentType.Cert作为第一个(也是唯一的)参数X509Certificate.Export,只有出口的公钥。在另一方面,指定X509ContentType.Pfx包括私钥如果存在

我可以发誓,我是上周看到不同的行为,但我必须已经安装了私钥时,我测试。当我今天删除了证书,并从头开始,我看到,那就是在导出的证书没有私钥。

其他提示

我发现下面的计划自己放心,证书的RawData属性包含只有公钥有帮助(MSDN关于这个不清楚),而上述关于X509ContentType.CertX509ContentType.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

有一个 OpenSSL的.NET包装可能会发现是有用的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top