If you use the smartcard Cryptographic Provider provided by T-Systems for the card, you’ll notice that by default you are prompted to enter the PIN of the smartcard via the standard keyboard, even if you have class 2 reader, which has its own pin pad. This behavior can be easily changed with a small change in the registry. Just open the Windows Registry Editor and navigate to the node HKEY_LOCAL_MACHINE\SOFTWARE\T-Systems\CardMiniDriverTCOS3\MSCP and change the value of the field usePinPad from false to true. The next time you are required to enter the PIN, you are asked to do it via the pin pad of the smartcard reader. You might need to remove and insert the smartcard to get this to work.
There are certain scenarios where it’s not feasible to require user interaction when accessing the private key of a smartcard. For example, a service does have the ability to provide a user interface. To use a key from a smartcard where a PIN is required, it must be provided to the smartcard using an alternative way. For some operations in .NET, one can use the CspParameters class to provide the PIN. But not all APIs which require smartcard access provide a way to use that class. The SSLStream is such a case. Here is a small extension method which sets the PIN for an X509Certificate2 instance:
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,
SafeNativeMethods.Execute(() => SafeNativeMethods.CryptSetProvParam(providerHandle,
SafeNativeMethods.Execute(() => SafeNativeMethods.CertSetCertificateContextProperty(
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,
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool CryptSetProvParam(
[In] byte pbData,
[DllImport("CRYPT32.DLL", SetLastError = true)]
internal static extern bool CertSetCertificateContextProperty(
public static void Execute(Func<bool> action)
throw new Win32Exception(Marshal.GetLastWin32Error());
The interesting piece here is, of course, the SetPinForPrivateKey method. It acquires a Win32 cryptographic context, sets the PIN and associates that pin with the certificate. Once you have an X509Certificate2 instance, you can set the PIN with just one line of code:
var certificate = GetCertificate();
The PIN is remembered until the X509Certificate2 instance is open.
This solution is taken from an stackoverflow article. I’ve just made an extension method out of it, converted all those magic numbers to enums and added a little bit of error handling.
If you use a Smartcard for cryptographic operations and get one of the errors above, the error might be in the configuration of your Smartcard Cryptographic service provider configuration. In my case I had a NetKey 3.0 card and got the error “The requested keycontainer could not be found” when accessing the private key. The error “The Local Security Authority Cannot Be Contacted” was thrown when I tried to use a certificate from the smartcard to establish a mutual authenticated SSL connection to a server.
The cause for this error was that the key length of the certificate on the smartcard was 2048 bits, but the Smartcard provider had a length of 1024 bits configured in the registry.
To fix the problem, I had to follow these steps:
- Open Regedit and navigate to HKEY_LOCAL_MACHINE\SOFTWARE\T-Systems\CardMiniDriverTCOS3\Applications\NKS V3.0\Key1.
- Set the value of the field KeySize to 2048 (if the key on your card has indeed a length of 2048 bits)
- Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\T-Systems\CardMiniDriverTCOS3\Applications\NKS V3.0\Key2
- Set the value of the field KeySize to 2048.
- Close Regedit.
- Open the Card Management tool, select the smartcard and navigate to the node Smartcard Base CSP
- In the context menu of that node click Remove Base CSP application from the card…
- Confirm the operation by entering the pin and click “Remove Base CSP application!” (seriously – who puts exclamation points on button labels?)
- After the operation completes, close the Card management tool.
- Remove the smartcard from the reader and insert it again.
- Open the Card management tool again. This will re-initialize the card.
Using smartcards with Windows is not as trivial as I thought it would be. Although Microsoft ships a Smartcard provider for its CryptoAPI for current versions of Windows (an update is available for older versions of Windows), most smartcards cannot be used out of the box. Every smartcard type requires its own implementation of a Cryptographic Service Provider (see http://msdn.microsoft.com/en-us/library/ms953432.aspx for more information).
The Netkey type of smartcards is used by T-Systems in Germany. They also offer a CSP module for Windows (x86 and x64) and PKCS#11 interface libraries for Linux, MacOs and Windows. It can be downloaded from the TeleSec website.
Once the CSP is installed, the Card Management software, which comes with the driver, can be used to map certificates from a smartcard into the Windows Certificate (either the store of the current user or the local machine).
This is the main view of the TeleSec Card Management software:
Each certificate on the card has its own node. If you click on it, the certificate is displayed in the right view. From there you can import it into the store of the current user. To import the certificate into the machine store, right-click the certificate and select “Save certificate in machine store”. Administrative rights are required for the latter operation. On Windows Vista you must start the Card management software with elevated privileges.