导出X.509证书没有私有密钥
-
23-08-2019 - |
题
我想这将是简单的,但显然事实并非如此。我已经安装了证书,具有私钥,导出,我想以编程方式,只有公共密钥导出。换句话说,我希望有一个结果等同于选择“不要导出私钥”,通过certmgr出口并出口到.CER时。
似乎所有的X509Certificate2.Export方法将导出私钥如果存在的话,作为PKCS#12,这是我想的正好相反。
有没有使用C#来完成这个任何方式,或者我需要开始挖成CAPICOM?
解决方案
有关谁比谁有可能在这迷迷糊糊中,我想通了。如果指定X509ContentType.Cert
作为第一个(也是唯一的)参数X509Certificate.Export
,只有出口的公钥。在另一方面,指定X509ContentType.Pfx
包括私钥如果存在
我可以发誓,我是上周看到不同的行为,但我必须已经安装了私钥时,我测试。当我今天删除了证书,并从头开始,我看到,那就是在导出的证书没有私钥。
其他提示
我发现下面的计划自己放心,证书的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
有一个 OpenSSL的.NET包装可能会发现是有用的。
不隶属于 StackOverflow