Tuesday, October 02, 2007

Self-signed SSL Certificate on Development PC

As I near deployment of a moderately large-scale ASP.NET 2.0 web application, I'm trying to wrap my head completely around all of the issues related to deployment.  One of the questions that keeps boiling up in my mind is how an ASP.NET web application, some of the AJAX stuff, IIS, and SSL all play nice together.

After doing some research online, and even asking some guys that run web sites for a living, I've come to the conclusion that this is definitely something that is best learned by doing.  So, I'm going to attempt to setup the whole package on my development machine.  I know enough about SSL to know that this won't be a perfect simulation.  I'm going to try to generate my own certificate, so I'll just have to pretend like I don't see Firefox telling me that the certificate is not from a trusted source or whatever - if I manage to get that far.  Here goes.

The Self-Signed Certificate

When searching for a method to make my own certificate, a couple of methods were commonly suggested on forums and blog articles:

  • SelfSSL - part of the IIS Resource Kit
  • MakeCert - seems to be bundled with Visual Studio
  • MS Certificate Authority.

I decided to try SelfSSL, since it seems to be the easiest at first glance.  So, I downloaded and installed the IIS Resource Kit (which claims to be for IIS 6.0, but people ay it works fine on Windows XP / IIS 5.1).  I did a custom install and only installed the IIS 6.0 Tools Documentation, SelfSSL, TinyGet, Web Capacity Analysis Tool, and WFetch.  The other stuff sounded useful, but I'll probably just forget about it and only use SelfSSL.

After the install finishes, running SelfSSL from the start menu will bring up a command box with the following info and prompt:

Microsoft (R) SelfSSL Version 1.0
Copyright (C) 2003 Microsoft Corporation. All rights reserved.

Installs self-signed SSL certificate into IIS.
SELFSSL [/T] [/N:cn] [/K:key size] [/S:site id] [/P:port]

/T               Adds the self-signed certificate to "Trusted Certificates"
                 list. The local browser will trust the self-signed certificate
                 if this flag is specified.
/N:cn            Specifies the common name of the certificate. The computer
                 name is used if not specified.
/K:key size      Specifies the key length. Default is 1024.
/V:validity days Specifies the validity of the certificate. Default is 7 days.
/S:site id       Specifies the id of the site. Default is 1 (Default Site).
/P:port          Specifies the SSL port. Default is 443.
/Q               Quiet mode. You will not be prompted when SSL settings are

The default behaviour is equivalent with:

selfssl.exe /N:CN=ADAM-IMS /K:1024 /V:7 /S:1 /P:443

C:\Program Files\IIS Resources\SelfSSL>

I decided to be gutsy and try it with all default settings - except to set the validity to 30 days instead of 7.

> selfssl.exe /V:30
> iisreset

Cool beans.  Now, if I look at the "Directory Security" tab in IIS for my default web site (or any of the site under that for that matter) I can click "View Certificate" and see the self-signed certificate I've installed.  There are some errors displayed about it not being from a Trusted Certificate Authority, but I expected that since I made it myself, and didn't get it from a CA like GeoTrust or Thawte or GoDaddy.

I'll try going to https://localhost now - I have just a dummy page set up there in the Default Site.  Ok - two warning dialogs popup.  The first, as I expected, told me that the certificate is not signed by a trusted CA.  The second warns me that the certificate is for ADAM-IMS, but I am viewing localhost.  I want to fix this second one, since Visual Studio usually opens up to localhost when debugging a web application.

> selfssl.exe /N:CN=localhost /V:30
> iisreset

There, that did the trick.  Now I just get the first warning.

Testing the App

Cassini, aka the Visual Studio Development Server, does not currently support SSL (and I doubt it will anytime soon).  Makes sense - it basically opens up a standard http server on a single port (usually 49587 or something like that).  SSL typically runs on port 443 of IIS, separate from the standard http server typically on port 80.  That is why most browsers go to port 80 automatically for http:// and go to port 443 automatically for https:// - of course, Microsoft could write Cassini to support SSL, and make some new convention for what ports are what on Cassini, but I don't think they will anytime soon since you can specify in your project settings that you want to debug your web application using IIS anyhow.  Cassini is for convenience, but you are getting in pretty deep by the time you are thinking about SSL.

So, I set my web app to run on IIS (at localhost/<project_name> for the application root) and fired it up.  Currently, I have to manually switch from http:// to https://, but I'll probably have my Master Page and login page redirect to https:// if a user attempts to connect insecurely.

Things went better than I expected when floating around my application, testing stuff and watching for popup warnings like "This page has encrypted and un-encrypted elements... do you want to display the un-encryted stuff?" I have tried to keep the eventual conversion to secure application in mind, and always follow these conventions:

  • When linking to an image, or another page in the web app, I always use either relative urls [e.g. "img/first.png"] or the ASP.NET application relative path [e.g. "~/dynamics/dynamics.aspx" or
  • I always use relative paths in CSS url("...") values

To be continued?

I'll keep messing around with this, and see if anything else pops up.

Useful things I came across in researching this:

blog.coryisakson.com - MakeCert, and redirecting to https://
Scott Guthrie: Enabling SSL on IIS 7.0 using Self-Signed Certificates - incase you have IIS 7.0, things look much easier
Rob Conery: SSL and Development - SelfSSL, by a guy whose blog I read regularly. Odd and cool that his blog would have this tucked away in the archives. 


Andrew Chen said...

Hi, I'm also testing my ASP.NET project on IIS6 and am using SSL to give permission to run using https://locolhost/Default.aspx

When I typed ">selfssl.exe /N:CN=localhost /V:30" I see a followup prompt asking me if I want to replace the SSL for site 1. If I type in "y" for yes I'd see the following message:

Failed to acquire the cryptographic context: 0x8009000f

Have you come across that as well?



Noffie said...

@andrew - Sorry, but I have never run into that.

This newsgroup post has a comment by a Microsoft personality who seems to think it is a bug in SelfSSL.

You ARE using IIS 6.0, correct? I have only ever used SelfSSL on IIS 5.2 -- something you might want to try: remove any existing ssl certificates from the web site(s) (in IIS) that you are trying to self-sign.

Also, make sure you are trying to apply the certificate to the correct web site (or one that exists... selfssl defaults to site 1, which you may have deleted long ago!).

You can specify the site using the /S:<site_id> argument on SelfSSL. Here's some instructions on how to do this using IIS6.

Eila Arich-Landkof said...

i wish to set the self signed certificate to a URL. however, i need the certificate hash.
what command will retrieve the certificate hash?

crazy said...

are you serious? self signed ssl is always a BAD idea.

SSL is about a layer of security and using a self signed SSL is NOT SECURE

Don't be so cheap Buy commercial SSL they start at $15

if you are saving the $15 you should not be be in this business


Noffie said...

@crazy: If you read the title, you'll see that I'm only recommending doing this for testing, on your own development computer.

Anonymous said...

two years later and this post was extremely helpful.

I am building a QA envrionment on Windows 2008 and it worked great.

Grateful you took the time to share!


ds r4 said...

I have tried this self sign SSL in windows server 2003. But it does not work for connecting hotmail server.

Unknown said...

adam, this is great material and so helpful when I came to sorting out my test environment, prior to putting an ecommerce site im developing live. You also mention a very good point about relative urls in order to prevent getting those popups! I've looked around and i'm gonna get a verisign ssl, here as its cheaper then verisign themselves - just thought i'd share what happened to me !

Thanks a lot!


Unknown said...
This comment has been removed by a blog administrator.

Disqus for A Nofsinger's Blog