¿Cómo proporcionar PIN para acceder a la tarjeta inteligente mediante programación?

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

  •  20-09-2019
  •  | 
  •  

Pregunta

Estoy utilizando certificados para asegurar mis comunicaciones entre el cliente y el servidor (sin código, sólo configuración de extremo). Los certificados se almacenan actualmente en ACOS5 tarjetas inteligentes. Todo funciona muy bien excepto que cada vez que WCF crea un nuevo canal para acceder al servidor, el conductor pide ACOS5 usuario que introduzca “PIN del usuario”. Por desgracia, sucede muy a menudo.

¿Hay alguna manera de configurar controlador para almacenar en caché PIN que el usuario ya ha entrado dentro del proceso actual, al menos por algún tiempo o cómo puedo almacenar en caché y proporcionar pin cada vez mediante programación dentro de una misma sesión?

He encontrado alguna utilidad en este artículo :

  

Esto se debe a que en las versiones anteriores   Ventanas de cada CSP caché de la   PIN introducido, pero Windows 7   de hecho convierte el PIN a un seguro   token y almacena en caché eso. Desafortunadamente   sólo hay una caché símbolo mundial   pero los CSP no pueden utilizar fichas   generada por los demás, por lo que en primer lugar el   inteligente CSP tarjeta que solicita y cachés   una ficha, a continuación, le pide y SSL   almacena su propio token (sobrescribir el   primero), entonces el sistema de tarjeta inteligente   le solicita de nuevo (ya que su caché   token se ha ido).

Pero no puedo utilizar la solución que fue propuesta por el autor. Entonces, ¿qué debería hacer?

¿Fue útil?

Solución

En realidad, yo he encontrado respuesta en mi pregunta: ¿el comportamiento descrito causada por fallo en los sistemas de tarjetas avanzada CSP v1.9. Después de cambiar a la aplicación Alladin eToken funciona como debería. Así que no puedo proporcionar el PIN del código, sino que es recordado por CSP después de entrar y la disponibilidad del código no es necesario. Más buenas noticias:. Usuario ve solicitud de PIN en el diálogo familiar de CSP en este caso

Otros consejos

Esta es una manera que encontramos y usamos desde hace muchos años en nuestra aplicación principal:

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());
        }
    }
}

El post completo y autor está aquí: http: // www.infinitec.de/post/2010/11/22/Setting-the-PIN-of-a-smartcard-programmatically.aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top