Click here to Skip to main content
15,867,594 members
Articles / Programming Languages / C#

Using a Smart Card Certificate with .NET Security in C#

Rate me:
Please Sign up or sign in to vote.
5.00/5 (13 votes)
5 Oct 2011CPOL8 min read 201.7K   12.2K   65   40
How to use smartcard certificates in your .NET application

Introduction

In this article, you will learn how to use smart card certificates in your .NET application. It covers most of the steps to achieve this from creating the certificate to selecting it in the smart card and using it to perform a PKCS11 signature with the security classes of .NET. In order to apply those concepts, you will need a PKI (Public Key) smart card. Those devices are nowadays very affordable and you can get one with a reader from vendors like Gemalto for less than 80$ (I'm not working anymore with this company...).

Background

This article doesn't demonstrate what you can do with a PKI infrastructure but will show you how easy it is (when you find out how to do it...) to use a smart card PKI device with .NET and C#. Those who have some experience with PKCS#11 library will understand what I mean!

Using a PKI Smart Card as a CSP Provider

You won't find a lot of code in this article because most of it is done by the framework itself, however I have concentrated in this article on many tricks that I have learned while using a smart card to license the database of our enterprise application.

The first step is to generate the PFX certificate which is the format that most smart card utilities use to install certificate on the card. This is a relatively easy process when you know the steps. The important thing is that the private key must be exported. After few searches, I found a short but very useful page that gives the solution and you can get it here.

You will need 3 utilities:

  • makecert.exe to create the certificate and its private key
  • cert2spc.exe to convert the certificate file .cer to the .spc format (Software Publisher Certificate)
  • pvkimprt.exe which will combine the .spc file and the .pvk into the desired PFX file (PKCS#12 format)
makecert and cert2spc are available with Microsoft SDKs and can be found in the "Program Files\Microsoft SDKs\Windows".
pvkimprt is an Office utility that can be downloaded from Microsoft WEB here.

In a DOS shell, you'll have to type the following commands after setting the correct path.

makecert -r -n "CN=CodeProject" -b 01/01/2000 -e 01/01/2099
-eku 1.3.6.1.5.5.7.3.3 -sv smartcert.pvk smartcert.cer
cert2spc smartcert.cer smartcert.spc
pvkimprt -pfx smartcert.spc smartcert.pvk

This is going to generate 2 files that we need to use, the smartcert.cer contains only the public key (although it is possible to include the private key) and the smartcard.pfx is a full RSA key pair that is protected by password because the private key is the most sensible part of a certificate. When generation is done, you will be prompted to give passwords.

Microsoft Next Generation Smart Card Framework

I'm not going to describe here this framework as you can find a lot of good articles on the WEB that do that. What you need to know is that this framework saves you a lot of code and burden to integrate PKI smart cards in a .NET application. Before the BaseCSP and minidriver architecture, you would have needed to use PKCS#11 and write a lot of interop code. Now the only thing you need to do is to use the proper CSP (Crypto Service Provider) for your smart card.

When you install the drivers of the smart card, the vendor will provide the necessary libraries that integrate within this framework. However even with the CSP architecture, there are 2 approaches depending on how recent the implementation of the vendor is. The first CSP architecture would be required from the vendor to write a complete CSP provider, while with the new BaseCSP architecture, the vendor would have written only a minidriver that seats below the BaseCSP.

Microsoft Smart Card CSP Architecture

Microsoft CSP Architecture

The next thing you need to do is to install the PFX certificate in the smart card. Any smart card vendor will provide a simple utility to do that. We're not talking here about certificate management which is far beyond that topic, but a simple Windows or WEB utility to upload the certificate to the card and this should take a PFX file as this is the standard for exchanging certificates. When you import the PFX file, you should be prompted for the certificate password that you entered when creating the certificate and also for a container name. The container name is what we will use to select the certificate.

Creating a CSP with the Smart Card Certificate

This is where the code begins! The first thing you need to do is to find out which CSP your card is using. Like I mentioned before, if your card is supported by the new BaseCSP then you will refer to the standard Smartcard CSP (Microsoft Base Smart Card Crypto Provider), if your card is of an older generation you may need to use the vendor specific CSP, for example the Gemplus GemSafe card would use "Gemplus GemSAFE Card CSP v1.0".

Those values can be found in the registry at the following place: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider.

Now that we know what CSP to use, let's get down to the code. The following lines create a CspParameters class that links you to the Smart card certificate. There are 2 key parameters in order to select the right certificate, those are the CSP name and the container name. The last parameter is the PIN code that you need to enter when using the certificate from card, basically a 4 PIN digit like the one of your SIM card or bank card.

C#
CspParameters csp = 
    new CspParameters(1, 
        "Microsoft Base Smart Card Crypto Provider",
        "Codeproject_1",
        new System.Security.AccessControl.CryptoKeySecurity(),
        pwd); 

Now that we have "connected" the CSP to the smart card, we can use the certificate to sign some data. Of course, the purpose of signing is that you verify the signature. The principle of a digital signature is that you sign some data with your private key and the recipient of your message will verify the signature using the public key that you can distribute.

I'm not going to go deep inside the signature mechanism as there are already a lot of articles on CodeProject regarding this subject and a lot more on the WEB. I just want to point out that a certificate is a TRUST asset, to be trusted it needs to have been issued by a trusted party, that's where company like Verisign or RSA come into place. In fact, it all depends on the level of trust you require. If you want to use the certificate for your personal usage, then you can use those utilities to create self-signed certificate that you can distribute to your friends.

In order to verify, we need the public key of our certificate. An easy way to get it is to create a RSACryptoServiceProvider using the CspParameters we just created, then simply export the public key to an XML format with the method ToXmlString(false). Then in the program that verifies the signature, you just create the key of the RSACryptoServiceProvider with the method FromXmlString(xmlKey) and use this CSP instance to verify the signature.

The complete code provided sign some data with the smart certificate and verifies the signature using the XML representation of the public key.

In a real secure environment, you would distribute the .CER file for example that contains only the public key and install it on the recipient certificate store.

Accessing the smart card certificate from a Windows Service or a WCF service running under Windows 7 or Windows Server 2008

I recently accessed the certificate on the card through a WCF service hosted with IIS7 on Windows 7 and I faced a singular issue. When calling the service, I got a message telling that the Smart card manager was not running. Accessing the card from ths application was perfectly working so I guessed that something was blocking the card when the code was executed by the IIS process.

I found out on some post that an SCard API called by the .NET Framework to access the card is failing with an E_ACCESS_DENIED error. An interesting post explains that thanks to the UAC and extended security in Windows 7 and Windows Server 2008 the old smart card API now fails when called from a NT service or a WCF service hosted with IIS (I haven't tried with one hosted in Windows service but the outcome is predictable).

The solution is to change the access right with the authorization API to grant access to the smart card resource manager to everyone! The only problem with that solution is that it needs to be applied every time the machine is restarted. A simple solution is to create a registry string under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.

Included is a short piece of code in C I found on the MSDN and which does the job.

Then there is the case of Windows Server 2008...
The authorization code will work on Windows 2008 ONLY if the machine is in a domain. So far, I could find any explanation (even asking on a MSDN forum), but my empiric experience shows that if you run this code on a server 2008 which is not in a domain, the call to GetNamedSecurityInfo returns 5 (Access Denied) and you cannot give the access to the SC resource manager.

Of course, this little code is not only useful if you need to access a smart card certificate but in any situation where you need to access a smart card resource from a windows service or a WEB service.

Points of Interest

After reading this article, you should be able to use a smart card certificate in a .NET application using the latest CSP framework of Microsoft. If you want to go further and find out what you can do with PKI, I suggest that you browse the CodeProject Cryptography & Security articles where you will find a lot of interesting subjects!

History

  • 13th August, 2011: Initial version
  • 5th October, 2011: Article updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Connect In Private
Singapore Singapore
Software Architect, COM, .NET and Smartcard based security specialist.

I've been working in the software industry since I graduated in Electrical and Electronics Engineering. I chose software because I preferred digital to analog.

I started to program with 6802 machine code and evolved to the current .NET technologies... that was a long way.

For more than 20 years I have always worked in technical positions as I simply like to get my hands dirty and crack my brain when things don't go right!

After 12 years in the smart card industry I can claim a strong knowledge in security solutions based on those really small computers!
I've been back into business to design the licensing system for the enterprise solution for Consistel using a .NET smart card (yes they can run .NET CLR!)

I'm currently designing a micro-payment solution using the NXP DESFire EV1 with the ACSO6 SAM of ACS. I can then add a full proficient expertise on those systems and NFC payments.
This technology being under strict NDA by NXP I cannot publish any related article about it, however I can provide professional consulting for it.

You can contact me for professional matter by using the forum or via my LinkedIn profile.

Comments and Discussions

 
GeneralRe: CSP not detecting smart card minidriver on remote desktop Pin
orouit3-Apr-13 15:56
professionalorouit3-Apr-13 15:56 
GeneralRe: CSP not detecting smart card minidriver on remote desktop Pin
mateusz_gallus4-Apr-13 21:19
mateusz_gallus4-Apr-13 21:19 
QuestionActivIdentity Card not Recognized w/sample code Pin
Harvey Flaisher29-Mar-13 7:12
Harvey Flaisher29-Mar-13 7:12 
AnswerRe: ActivIdentity Card not Recognized w/sample code Pin
orouit1-Apr-13 0:23
professionalorouit1-Apr-13 0:23 
QuestionAccessing the smart card certificate from a Windows Service Pin
undeklinable13-Nov-12 0:03
undeklinable13-Nov-12 0:03 
AnswerRe: Accessing the smart card certificate from a Windows Service Pin
orouit14-Nov-12 17:42
professionalorouit14-Nov-12 17:42 
QuestionRead certificate from client machine Pin
Dragan Jovanoski21-Sep-12 23:44
Dragan Jovanoski21-Sep-12 23:44 
AnswerRe: Read certificate from client machine Pin
orouit4-Oct-12 20:31
professionalorouit4-Oct-12 20:31 
I'm not sure how you wish to do that but, the smart card certificate should be accessed like a certificate the store using windows or .NEWT API.

Please detail.
Software Architect, COM, .NET and Smartcard security specialist.

Questioniis 7.5 mutual authentification with gemalto smart card Pin
xfocus2928-Aug-12 0:25
xfocus2928-Aug-12 0:25 
AnswerRe: iis 7.5 mutual authentification with gemalto smart card Pin
orouit7-Sep-12 18:20
professionalorouit7-Sep-12 18:20 
QuestionUser Authentication Pin
sys2826-Jun-12 6:28
sys2826-Jun-12 6:28 
AnswerRe: User Authentication Pin
orouit11-Aug-12 1:42
professionalorouit11-Aug-12 1:42 
Questiongemalto .net smart card and reader Pin
SARP CEVİK6-Jan-12 7:22
SARP CEVİK6-Jan-12 7:22 
AnswerRe: gemalto .net smart card and reader Pin
orouit26-Jan-12 16:05
professionalorouit26-Jan-12 16:05 
GeneralMy vote of 5 Pin
Sergio Andrés Gutiérrez Rojas5-Oct-11 7:35
Sergio Andrés Gutiérrez Rojas5-Oct-11 7:35 
GeneralRe: My vote of 5 Pin
orouit26-Jan-12 16:03
professionalorouit26-Jan-12 16:03 
QuestionRead certificate name Pin
ingbabic2-Oct-11 23:42
ingbabic2-Oct-11 23:42 
AnswerRe: Read certificate name Pin
orouit3-Oct-11 15:23
professionalorouit3-Oct-11 15:23 
GeneralRe: Read certificate name Pin
pavanreddy6129-Jul-14 18:26
pavanreddy6129-Jul-14 18:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.