سؤال

اعتقدت أن هذا سيكون واضحا ولكن يبدو أنه ليس كذلك. لدي شهادة مثبتة تحتوي على مفتاح خاص، وقابل تصدير، وأريد تصديره برمجيا مع المفتاح العام فقط. بمعنى آخر، أريد نتيجة تعادل اختيار "لا تصدير المفتاح الخاص" عند التصدير من خلال Certmgr وتصدير إلى.

يبدو أن جميع أساليب x509certificate2.export ستصدر المفتاح الخاص إذا كان موجودا، كما PKCS # 12، وهو عكس ما أريد.

هل هناك أي طريقة باستخدام C # لإنجاز هذا، أو هل أحتاج إلى بدء الحفر إلى كابيكوم؟

هل كانت مفيدة؟

المحلول

لأي شخص آخر قد يعثر على هذا، احسبته. إذا حددت 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();
    }
}

يخرج ما يلي:

Orighar: Rawdata.length = 1337، Haspridvey = True Cert a: rawdata.length = 1337، haspridvey = false، certbytes.length = 1337 cert b: rawdata.length = 1337، haspridvey = true، certbytes.length = 3187 cert c: rawdata.length = 1337، haspridvey = false، certbytes.length = 1337 rawdata يساوي rawdata الأصلي: صحيح

هناك Openssl .NET Wrapper. قد تجد مفيدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top