كيفية توفير PIN للوصول إلى بطاقة SmartCard برمجيا؟

StackOverflow https://stackoverflow.com/questions/2068005

  •  20-09-2019
  •  | 
  •  

سؤال

أنا أستخدم شهادات لتأمين اتصالاتي بين العميل والخادم (بدون رمز ، فقط تكوين نقطة النهاية). يتم تخزين الشهادات حاليًا في بطاقات ACOS5 الذكية. كل شيء يعمل بشكل جيد للغاية باستثناء أنه في كل مرة يقوم فيها WCF بإنشاء قناة جديدة للوصول إلى الخادم ، يطلب برنامج تشغيل ACOS5 من المستخدم إدخال "دبوس المستخدم". لسوء الحظ ، يحدث في كثير من الأحيان.

هل هناك أي طريقة لتكوين برنامج تشغيل لذاكرة التخزين المؤقت التي أدخلها المستخدم بالفعل في العملية الحالية على الأقل لبعض الوقت أو كيف يمكنني تخزين PIN وتوفيره في كل مرة برمجيًا في نفس الجلسة؟

لقد وجدت بعض مفيد في هذا مقالة - سلعة:

هذا لأنه في الإصدارات السابقة من Windows ، يقوم كل CSP بتخزين PIN الذي أدخلته ، لكن Windows 7 يقوم بالفعل بتحويل الدبوس إلى رمز آمن واختداءات مخبأة. لسوء الحظ ، لا يوجد سوى ذاكرة التخزين المؤقت الرمزية العالمية واحدة فقط ، لكن لا يمكن لـ CSPs استخدام الرموز المميزة التي تم إنشاؤها من قبل الآخرين ، لذا فإن البطاقة الذكية CSP يطالبك واختبطك بالرمز المميز ، ثم يطالبك SSL واختزال الرمز المميز الخاص به (الكتابة فوقها الأولى) ، ثم يطالبك نظام البطاقات الذكية مرة أخرى (لأن الرمز المميز المخزنة له).

لكن لا يمكنني استخدام الحل الذي اقترحه المؤلف. اذا ماذا يجب أن أفعل؟

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

المحلول

في الواقع ، لقد وجدت إجابة على سؤالي: السلوك الموصوف الناجم عن الخلل في أنظمة البطاقات المتقدمة CSP V1.9. بعد التبديل إلى تطبيق Alladin Etoken يعمل كما ينبغي. لذلك لا يمكنني تقديم دبوس من الكود ولكن يتذكره CSP بعد الدخول والتوفير من التعليمات البرمجية غير مطلوب. المزيد من الأخبار الجيدة: يرى المستخدم طلب PIN في مربع حوار مألوف من CSP في هذه الحالة.

نصائح أخرى

هذه طريقة وجدناها ونستخدمها من سنوات عديدة في تطبيقنا الرئيسي:

static class X509Certificate2Extension
{
    public static void SetPinForPrivateKey(this X509Certificate2 certificate, string pin)
    {
        if (certificate == null) throw new ArgumentNullException("certificate");
        var key = (RSACryptoServiceProvider)certificate.PrivateKey;

        var providerHandle = IntPtr.Zero;
        var pinBuffer = Encoding.ASCII.GetBytes(pin);

        // provider handle is implicitly released when the certificate handle is released.
        SafeNativeMethods.Execute(() => SafeNativeMethods.CryptAcquireContext(ref providerHandle, 
                                        key.CspKeyContainerInfo.KeyContainerName, 
                                        key.CspKeyContainerInfo.ProviderName,
                                        key.CspKeyContainerInfo.ProviderType, 
                                        SafeNativeMethods.CryptContextFlags.Silent));
        SafeNativeMethods.Execute(() => SafeNativeMethods.CryptSetProvParam(providerHandle, 
                                        SafeNativeMethods.CryptParameter.KeyExchangePin, 
                                        pinBuffer, 0));
        SafeNativeMethods.Execute(() => SafeNativeMethods.CertSetCertificateContextProperty(
                                        certificate.Handle, 
                                        SafeNativeMethods.CertificateProperty.CryptoProviderHandle, 
                                        0, providerHandle));
    }
}

internal static class SafeNativeMethods
{
    internal enum CryptContextFlags
    {
        None = 0,
        Silent = 0x40
    }

    internal enum CertificateProperty
    {
        None = 0,
        CryptoProviderHandle = 0x1
    }

    internal enum CryptParameter
    {
        None = 0,
        KeyExchangePin = 0x20
    }

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptAcquireContext(
        ref IntPtr hProv,
        string containerName,
        string providerName,
        int providerType,
        CryptContextFlags flags
        );

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool CryptSetProvParam(
        IntPtr hProv,
        CryptParameter dwParam,
        [In] byte[] pbData,
        uint dwFlags);

    [DllImport("CRYPT32.DLL", SetLastError = true)]
    internal static extern bool CertSetCertificateContextProperty(
        IntPtr pCertContext,
        CertificateProperty propertyId,
        uint dwFlags,
        IntPtr pvData
        );

    public static void Execute(Func<bool> action)
    {
        if (!action())
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
    }
}

المنشور الكامل والمؤلف هنا:http://www.infinitec.de/post/2010/11/22/setting-the-pin-of-a-smartcard-programmally.aspx

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