Implementing SmartCard Authentication with ASP.NET

9:19 PM j. montgomery 45 Comments

UPDATE: An updated version is out. Read more about it here.

http://securitythroughabsurdity.com/2010/05/smart-card-authentication-module-update.html

Table of Contents

This is a more complete follow-up article on how to implement Smart Card Authentication in ASP.NET using Http Modules. Sample code in C# is now available here. VB.Net Projects to be posted soon.
You can also download a PDF version of this article here.
I. Introduction
II. Building and Installing the Smart Card HttpModule
III. IIS Configuration
IV. Implementing SmartCardAuthenticationModule
V. SmartCardAuthenticationEventArgs Implementation
VI. SmartCardIdentity Implementation
VII. SmartCardPrincipal Implementation
VIII. Additional Implementation Details
IX. Implementing Authorization in ASP.NET
X. Further Reading

45 comments:

  1. I can't download the pdf. Windows are show the name/pass screen when i click for download. Plase send the pdf for my e-mail: tcfialho@gmail.com i need that for do my monografy.

    ReplyDelete
  2. Hello...

    i think this project is one and the best web based smart card authentication project...I will try to use it , i hope i can do it..But i can not see photos?What is the problem?

    ReplyDelete
  3. Thanks! I believe the place where I'm hosting my images is being reorganized. I'll look into it.

    You will be able to see the pictures in the PDF for now until I can fix the links.

    ReplyDelete
  4. How is about using protected web application from Firefox on Linux, using smart cards? Is this possible?

    Thanks,
    Mickey

    ReplyDelete
  5. Yes, it's certainly possible to use a Smart Card with Firefox on Linux!

    See Using DoD CAC and SmartCard Readers on Linux

    ReplyDelete
  6. I have all of this code working. I am able to see the CAC (SMARTCARD) information in the classes.

    How can I reference the properties in the class on a aspx page. The classes are instantiated outside the page and not sure how to reference the classes within a aspx page.

    Using asp.net 2.0

    ReplyDelete
  7. The HttpModule stores the objects such that you can retrieve them from an ASPX page you are in.

    The SmartCardPrincipal Object is stored in the 'Me.User' property of the Page object:

    SmartCardPrincipal smartCardPrincipal = (SmartCardPrincipal)this.User;

    Likewise, the SmartCardIdentity object is stored in the 'Me.User.Identity' property of the Page object:

    e.g. SmartCardIdentity smartCardIdentity = (SmartCardIdentity)this.User.Identity;

    Does this answer your question?

    ReplyDelete
  8. Hi,
    I was wondering if anyone reading this might have .Net 2.0 version of this functioning and if so is there anyway to get a sample f their code. I just can't seem to get it to work for me.

    ReplyDelete
  9. Scott - what sort of issues are you having?

    ReplyDelete
  10. Hi, I'm trying get a certificate from a smart card. Everything is ok, but if the user don't close the browser the data of the certificate are always available, even if the user has retired the card. My application (asp.net) is shared by several users, and I can't close the browser for each use.
    How I can release the information of the certificate after I used it?
    Thank.
    Antonio.

    ReplyDelete
  11. Hi,

    I try to test your sample.

    I work with Visual 2005, when i open the project, Visual want to convert it.

    I have try two ways,

    1: I test the project unedited(except web.config cfr. ReadmeFile), but there's a problem with the global.asax line that have a syntax error ( Application Codebehind="Global.asax.cs" Inherits="SmartCardAuth.Global")

    Is it a know problem, or is it IIS or .NET version problem?


    2 : I test with the project converted by visual;
    Problem ("The type or namespace name 'SmartCardAuthentication' could not be found (are you missing a using directive or an assembly reference?")

    What should I do to Add assembly reference?


    Is there someone to help me?

    Thanks in advance.

    ReplyDelete
  12. Hello..

    We are developing an application on Smart Card.. We have no documentation and no clue on how to get started. It would be nice if you could get some help from someone who has been through it already.

    As it is,we couldnt get this sample code working as we are using VS.NET 2005.

    Could you please help us out?

    Thanks in advance.

    ReplyDelete
  13. Shweta,

    You mentioned you are using VS 2005, are you using the built in Web server or did you setup your web application in IIS?

    ReplyDelete
  14. Thank you very much! Your method was eloquently documented and helped me tremendously with setting up a working authentication model. I did have to make some changes to support role management across multiple systems, but everything else worked very well. I am still having a little bit of trouble integrating this with roles for an ASP.NET Menu control, but that's a whole other issue. Thank you again.

    ReplyDelete
  15. Chase - glad you found it helpful.

    I've got a 2.0 version I need to package up and release - it sound similar to what you've done. It's built around the RoleProvider model in .NET 2.0.

    I've been experimenting with a couple other ideas as well. When life slows down I plan to write them up and post them.

    ReplyDelete
  16. Thank you for an excellent article. It is the only useful resource I could find on the topic.

    I have one question. You use public key to map certificate to the database user account. What will happen when the certificate expires and the user gets a new one? The public key will change and the mapping broken. Why do not use subject string for the mapping? My understanding is that it survives certificate renewal.

    Thanks,

    Sergey

    ReplyDelete
  17. Sergey,

    No problem! Glad you found it helpful...

    You are correct - typically the Subject Name won't change...however, it would be trivial for an attacker to create an X509 certificate with a Subject name that matches another X509 certificate they wanted to impersonate...the public key and private key would be different, as well as the Certificate Chain so it still may be blocked at IIS or by some additional checks you could add in code.

    However, in the spririt of Defense-in-depth, I decided to use a hash of the public key because the public key is cryptographically generated and *I BELIEVE* it would be next to impossible to invent a duplicate smart card that had the SAME public key (public keys are KNOWN/can be discovered) without knowning the private key that goes with it. It's possible I'm misguided on this point so your mileage may vary.

    What you could do is check both Subject and Public Key Hash and if the public key changes, move to do a renewal. In my particular situation, I want eyes on certificate information for a renewal approval - your situation may not need to be as strict.

    ReplyDelete
  18. Does anyone has the complete DataAccess.cs class?

    The following methods are missing:
    EnrollUser
    SelectAllUsers
    SelectUserRolesByUserID
    UpdateUserByUserID
    AddUserRoleByUserID
    DeleteUserRoleByUserID

    ReplyDelete
  19. It should be in the source code contained in the zip file. Check there.

    thanks!

    ReplyDelete
  20. I looked everywhere I didn't see them. I already reimplemented them though. Please open the zip and go to DataAccess.cs. Also I changed DataAccess.cs to connect to an Oracle Database.

    Thanks
    Fernando

    ReplyDelete
  21. Fernando, you are correct! I did leave those out aparently...thanks for letting me know. When I get some time, I'll update the archive will the updated DataAccess class.

    Thanks again.

    ReplyDelete
  22. No problem. Since I like your article so much once I have something working with Oracle I will tell you and then I send the updated code.

    Thanks again
    Fernando

    ReplyDelete
  23. Fernando, glad you liked the article. I'll happily accept any code you would like to provide.

    ReplyDelete
  24. Thanks, a good introduction into using smart cards & client certs.

    ReplyDelete
  25. Regarding: DataAccess.cs class?

    The following methods are missing:
    EnrollUser
    SelectAllUsers
    SelectUserRolesByUserID
    UpdateUserByUserID
    AddUserRoleByUserID
    DeleteUserRoleByUserID

    Any chance of posting these or email just the DataAccess.cs to me? I could write them out by hand, but if you have the code it would save a lot of time!
    thanx!
    julian

    ReplyDelete
  26. Help,

    I was successful in setting up SSL and I am trying to use the demo project but I am getting,

    Problem ("The type or namespace name 'SmartCardAuthentication' could not be found (are you missing a using directive or an assembly reference?")

    What should I do to Add assembly reference?

    ReplyDelete
  27. Dan,

    I'll need a bit more information - is this error message showing up within Visual Studio (when you build) or is it showing up when you actually load the site?

    First guess is, yes, you'll need to make sure to update your assembly references within the web project.

    ReplyDelete
  28. This is Fernando again. I have the changes I talked about back in February. Basically using Oracle as well. I will be sending file changes only. Let me know where to send them.

    ReplyDelete
  29. Sent it to email provided. Oracle script is also included.

    ReplyDelete
  30. Great Info! Any luck on that Oracle version? reten and then the @ gosolstice.com

    ReplyDelete
  31. That Oracle version is coming. I've been so swamped I have barly been on the blog the past month. I do have the Oracle code and will post it next break I get.

    ReplyDelete
  32. This comment has been removed by a blog administrator.

    ReplyDelete
  33. I really liked this article. But I have a few questions. I looked for an email address to send to, but I didnt find one.

    Anyway:
    You mention at the beginning that forms authentication is bad because it sends information to the client and thus must be considered suspect. You also mention that the encrypting and decrypting of the authentication ticket adds extra processing overhead.

    Looking at your code and explanations, what I cant figure out is this: You authenticate the user and then store the user's information in the Context.User object. 1-How is that better than storing it in say the session? Where exactly is this Context.User stored? I am assuming it is on the server somewhere in order to not violate the "sending info to the client" point you made. But that leads me to question 2-Assuming that the Context.User is on the server, and the Context lifecycle is from the beginning of the request until the end of the response, how is session state managed securely? Authentication state is not stored between requests, then dont you have to authenticate every time a request comes in? And doesnt that mean you are doing a database user lookup at every request, which could be worse overhead than a cookie decrypt?

    Clearly I am missing something obvious but the MSDN documentation I can find is atrocious. After reading an article you linked to here about session fixation which states that ANY authentication methodology that isnt coupled to session is vulnerable to session fixation attacks, I really want to understand how your solution deals with these situations.

    Thanks for your time.

    ReplyDelete
  34. Can you shed some light on CryptoUtility? You reference it in code but what is it supposed to do? Can you provide code?

    ReplyDelete
  35. You make a great point - I also post on SANS AppSec Street Figher blog and have posted to posts on Session issues in ASP.NET.
    http://blogs.sans.org/appsecstreetfighter/2009/06/14/session-attacks-and-aspnet-part-1/

    https://blogs.sans.org/appsecstreetfighter/2009/06/24/session-attacks-and-aspnet-part-2/

    You are completely correct. As this stands, anyone who can log into a site with a smart card can pull of a session fixation attack UNLESS you couple session and authentication together. To mitigate this issues you'd simply store something on the smart card in session and then check it on every subsequent request.

    ReplyDelete
  36. The CryptoUtility class is in the zip file - you can view it there. Essentially it provides the ability to perform some additional checks on the SmartCard - such as validating the X509 certificate's hash.

    ReplyDelete
  37. Jason,

    I'm not sure how to go about setting up the IIS portion of things. I'm confused about what the mechanism is for prompting a user who accesses a CAC-enabled website for a cert.

    I am trying to set up a dev/test environment (on my local laptop initially which has IIS 5.1/XP) for a DoD website which uses DoD CAC authentication. I have ASP .NET code which will do everything in terms of associating the cert with a user, etc. The problem I'm having is setting up IIS.

    Is the mechanism which prompts a user for the cert the SSL cert that you apply for? I'm guessing I need to apply for this SSL cert via the DoD in some way and then attach that SSL cert to my website in IIS. Right now,I have no option for selecting an SSL cert via the IIS certificate wizard other than selecting the existing certificate option and using a cert that looks like it comes from my company's CA(?) but I take it this won't work if I want my site set up for use with DoD CAC's. If I use my company's cert, I get a 403.7 (client certificate required) error every time I try to access the cert enabled site (I tried setting certificate authentication up on the built in IIS Admin site).

    I guess what I am asking is what is the mechanism which would prompt me for my DoD CAC cert? I do have all the trusted root certs/intermediate certs intalled using a DoD tool called InstallRoot. I personally have a CAC which is issued by DOD CA-20... just need my IIS website to be able to prompt for it... is it the SSL cert that is the missing piece here?

    ReplyDelete
  38. Setup for getting IE to prompt for Client Certificate / CAC is two-fold:

    1. SSL Enable IIS and turn on the option that prompts for Client Certificates.

    2. Have an X509 certificate installed in your Personal Certificate Store for the local user that has a Key Usage designated for this purpose.

    The DoD CAC cards have the following Enhanced Key Usage attributes set:

    Client Authentication (1.3.6.1.5.5.7.3.2)
    Secure Email (1.3.6.1.5.5.7.3.4)
    Smart Card Logon (1.3.6.1.4.1.311.20.2.2)

    When IE see's the requirement for an SSL Client Certificate when making the initial SSL connection to IIS and ALSO has a Cert installed in the client computer's Local Personal Store with the Client Authentication Enhanced Key attribute set it will then prompt - AS LONG AS THE CLIENT CERTIFICATE CERTIFICATE CHAIN IS VALID (meaning your client machine needs to trust the Certificate Authority that signed your client certificate).

    For a testing environment, I recommend setting up a Root Certificate Authority (CA) by adding the Certificate Services Role on a Windows 2008 Server. Once you have set this up, you can submit and sign your own certificates for development and testing - no physical CAC needed. Then you can generate a client certificate using the Certificates MMC snap-in and use Certificate Services on Windows 2008 Server to sign them. Once you have the X509 Client Certificates you can then install them on your client computers and test.

    ReplyDelete
  39. Hey Jason,

    Thanks for the response. This is really helpful and I appreciate it.

    I do have a personal certificate from my CAC (3 actually... 2 DOD EMAIL CA-20 and one DOD CA-20) which can be seen in the personal certificate store in IE. One of these does have the Enhanced Key Usage setting for Client Authentication and I get prompted for a cert when I try to access the production system.

    Thanks largely to your help, I think I am close to understanding how it works... is it true that in order to get my website to prompt for a cert that the SSL cert I use for my IIS website needs to be signed/issued by an authority in the same chain as the authority that issued my CAC certs that are stored in my personal cert store? If the answer to this is yes, then I think I at least have some understanding.

    Also, can I set up my own cert authority to dispense certs in Windows 2003 Server as opposed to 2008? 2003 will be what is in our dev/test environment eventually.

    ReplyDelete
  40. > is it true that in order to get my website
    > to prompt for a cert that the SSL cert I
    > use for my IIS website needs to be
    > signed/issued by an authority in the same
    > chain as the authority that issued my CAC
    > certs that are stored in my personal cert
    > store?

    Not quite, but close - the most important thing to realize is that PKI is all about trust of certificates. The Certificate chain needs to be validated, so the crypto signatures need to match up the chain and the Root and Intermediate CA's need to be trusted. The Server SSL/TLS certificate can have a different cert chain (signed by different CA's) so long as both the server and client TRUST the other certificate's CA's.

    So the Web server must have the Client Certificate's Root/Intermediate CA's in it's Trust Store. That allows the Server to validate the client. The Client needs to have the Server's Root/Intermediate CA's in it's Trusted Store. This allows the client to validate the server.

    > ..can I set up my own cert authority to
    > dispense certs in Windows 2003 Server as
    > opposed to 2008? 2003 will be what is in
    > our dev/test environment eventually.

    Yep, Server 2003 also has Certificate Services and you can setup a CA there. Just make sure you install the CA's certificate on all your clients and servers that need to validate certs chains signed by that CA.

    ReplyDelete
  41. Hi Jason. I echo the sentiments of all other commenters that this is by far the best article and code posting anywhere on the topic. I'm just wondering if you can explain how I can pull the details off my smart card. Does this require an activeX control or does windows just automagically 'do it'?
    Cheers Hamish

    ReplyDelete
  42. thanks Hamish - glad you found it helpful. You are correct - if you want to read from smart card storage (i.e. data not stored in the X.509 certificate) the software to read that data must be running directly on the client. An ActiveX control would work and I also believe you might be able to accomplish this by writing a custom Identity Provider for Windows Identity Foundation (WIF) and CardSpace.

    ReplyDelete
  43. Hello Jason,
    I like to thank you for such a detail article on SmartCard authentication. In your zip download there is SQL script but I could not find the database. Is there a database available?

    Thanks,
    fanzi

    ReplyDelete