ASP.Net TypeKey authentication
TypeKey is an online authentication service that provides a single sign-on (SSO) experience to the websites that support it.
My goal for this TypeKeySecurity C# library is to allow ASP.Net programmers to easily take advantage of this service.
Download the code (includes source, binaries, documentation and a demo).
Merits of SSO solutions can be argued (there is trade off between security and convenience) and those of TypeKey can be argued as well (in comparison to similar systems like Passport).
But I am convinced that for many personal and community sites using an SSO can make the developer's life easier (no need to re-implement the same code and DBs every time), as well as the user's (no need to register a new account for each site and remember all the passwords). TypeKey happens to be rather simple and open, which makes it a good choice.
Read the TypeKey FAQ for more info.
The source file includes build files for NAnt and VS.net 2003.
Three tasks are available for NAnt, "build", "doc" and "clean". Re-building the documentation ("doc") requires NDoc to be installed.
Four simple steps ;-)
- Register a TypeKey account at https://www.typekey.com/t/typekey and get a site token.
- Copy the TypeKeySecurity.dll file into the /bin directory of your ASP.Net project.
- Modify your web.config to disable any other kind of built-in authentication (Windows, Passport, ...), activate the TypeKeyAuthenticationModule and configure your site key. See the example of web.config configuration below and in the documentation.
- Use the TypeKeyIdentity object in your code, by declaring "using TypeKeySecurity;" and then "TypeKeyIdentity id = (TypeKeyIdentity)Context.User.Identity;".
<authentication mode="None" />
type="TypeKeySecurity.TypeKeyAuthenticationModule, TypeKeySecurity" />
<add key="TypeKeySecurity.Token.Value" value="0123456789ABCDEF0123" />
Read the documentation online (CHM format).
The demo site consists of four files:
- /default.aspx: Demo UI.
- /default.aspx.cs: Code-behind for default.aspx. Doesn't need to be compiled (it gets compiled when default.aspx is first served).
- /web.config: Simple config file. You need to modify it to use your own site token, provided when registering with TypeKey.
- /bin/TypeKeySecurity.dll: The library wrapping the TypeKey authentication service.
Configure your web server to point to this directory and load /default.aspx page into your browser, using your server's url. You should see a page with a link to log in.
Click it and sign in with a TypeKey account. You should be sent back to that page, which should now show the information for the user you logged in with.
The page sets a cookie so that the authentication persists throughout the session.
TypeKeyIdentity class overview
When the TypeKeyAuthenticationModule is hooked into with your ASP.Net site, you can find out about the current user through the TypeKeyIdentity object, available using "(TypeKeyIdentity)Context.User.Identity;".
This identity object will tell you whether the user is currently authenticated, how long it has been since he was authenticated by TypeKey, his login name (the TypeKey unique identifier), his email address and his display name (nick).
For privacy protection, unless you specifically need the user's email, TypeKey will only provide you with a SHA-1 hash of the email. If you do need that information, the login prompt shows that the user's email address will be shared with your site.
TypeKey uses your login name as the unique identifier. But in the case where you need to key your database using the user's ID, using a string may seem weird. So the TypeKeyIdentity also exposes the MD5 hash of the login name for this purpose. It is a 128 bits integer. That can be used in MS SQL using the uniqueidentifier datatype.
Let me know if you know of a better way to derive a (smaller) numerical identifier from the login name :-)
I had taken a stab at the TypeKey protocol while it was in Beta. I just found out the official TypeKey protocol documentation was published (via Srijith's post).
The format for the signature was the main missing element. It uses DSA (Digital Signature Algorithm).
TypeKey returns the DSA signature in the format "<base64R>:<base64S>". But the DSA class in the .Net framework expects one byte array.
Looking at Mono's code for DSA showed that .Net expect the byte array to contain R followed by S.
Since both R and S have a fixed sized the internal of the DSA implementation can easily split them apart when needed.
Reading the DSA public key:
The other problem with implementing the DSA signature check is that TypeKey provides its public key online using the format "P=<decimalP> Q=<decimalQ> G=<decimalG> pub_key=<decimalY>". But the crypto classes in the .Net framework need all these as byte arrays.
Mono solves this problem by implementing a BigIntegers class in the Mono.Math namespace, which doesn't exist in the MS .Net framework.
I used their implementation for a while, but ran into signature problems that required me to declare the Mono.Security.dll in the machine.config (using <add assembly="Mono.Security, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"/>). But I don't want people who use the TypeKey authentication provider to have to do that...
I chose to use Chew Keong TAN's implementation of BigIntegers at the CodeProject .
Things would have been much easier if the public key (P,Q,G,Y) had been stored as binary with base64 encoding instead of decimal.
The main security improvement that should be included in the protocol is having the signature be site specific. Srijith discussed this risk, which allows authentication assertions to be replayed from one site to another. A trivial way to mitigate this is to have the signature apply to "<email>::<name>::<nick>::<ts>::<t>" where t is the site token.
I also think TypeKey should offer a single sign-out solution. Currently, if you log into two blogs, you get logged into those two sites and also the TypeKey site. But when you log out from one of the blogs, you get logged out of the TypeKey site, but not the other blog. This is a problem if you are using a public computer (say in a library or internet cafe).
Writing the code for the sign-out in this library was kind of a pain. The Passport sign-out seems more elegant and keeps urls cleaner. For TypeKey to implement a similar model is they would need to keep track of the sites you logged in within a session and store a "logout gif" url for each registered site.
One more issue is pointed out in the TypeKey: there should be minimal time skew between the TypeKey server and the site requesting the authentication. NTP can be used for that purpose. For example, I noticed that my own box has a 5 minute time difference with TypeKey. This can be used to enhance a cross-site replay (see first security threat) and can also be a problem if you need a very tight control over the time window you want to apply to users authenticating (which most TypeKey-enabled sites should not).
TypeKey service dies
The best mitigation I can think of is that you should store the email of the user (cleartext or SHA-1, it doesn't matter) along with the rest of the profile data you persist. This would allow you to migrate away from TypeKey by using the ownership of an email address as an authentication mechanism.
I included a webcontrol to display a "sign-in/sign-out" logo, but I want to make it easier to tweak (CSS based), as well as provide nicer logos. I also want to provide some hooks and events in the authentication lifecycle for customization.
Since I don't run my own CVS server anymore, I started a project on SourceForge. It's called TypeKeyDotNet.
I hope you'll find this component useful. Let me know if you have questions or comments.
All feedback is welcome :-)
Update: A CPAN Perl library to interface with TypeKey: Authen::TypeKey.______________________________________
thx for your effort.
I applied your TypeKeyDotNet for my blog and It's ran very well.
Thankyou very much!Posted by: LikeJAzz (September 14, 2004 02:46 PM) ______________________________________
Thanks for trying it and letting me know ;-)Posted by: Julien (September 21, 2004 06:54 AM) ______________________________________
I am a full time graduate student. We are planning to implement an application(basically a novice web service)in .NET where Digital signatures are used for security reasons. Can I apply your Type key in my project?
Sure go ahead. The code is all GPL and available from sourceforge and/or the zip file posted in the article.
Do you have any more details on what you're trying to build?
Thought you'd like to know: the vulnerability described by Srijith was patched in TypeKey version 1.1 (http://www.movabletype.org/docs/tk-apps.html ). Version 1 is still supported for backward compatibility, but version 1.1 is more secure. The app can specify what version it uses, by passing the "v=1.1" parameter. The format of the 1.1 signatures is described in the spec.
Hope that helps!Posted by: Ezra (November 16, 2004 01:33 PM) ______________________________________
Sounds good. Thanks a lot pinging me.
I'll be sure to check it out and update my Asp.Net/TypeKey authentication module ( http://typekeydotnet.sourceforge.net/ ) to use the improved protocol.
I applied your TypeKeyDotNet for my blog and It's ran very well.Posted by: fermuar (January 18, 2006 11:48 AM) ______________________________________
I have seen some TypeKey hacks out there, with any free/opensource projects I guess they will pop up. Might go with a commercial version instead.Posted by: tucex (January 23, 2006 07:49 PM)