Generating a self-signed certificate in memory for WCF encryption

Hi folks,
I've been looking into some of the ways of securing my WCF communication.  What I am building is a client/server application, both in .Net.  They communicate over WCF using nettcp over an intranet only.  My concern is how to best encrypt the communication without adding complication to the installation process.  It looks to me like using a self-signed certificate only on the server might be my best bet but I don't want the customer to have to deal with having to generate and install a certificate.  So my thought was to generate the certificate on the server with .net using a third-party class I found on the internet (http://btburnett.com/2009/05/create-a-self-signed-ssl-certificate-in-net.html). I was thinking I would just generate the certificate with an absurdly late expiration date when the server runs for the first time but then I came up with another idea.  

Does anyone know if it would be possible to generate the certificate each time the server starts and just keep it in memory, then assign it to WCF to use?  I was thinking that by doing this I could avoid having to store the certificate on the server which might be a good thing.  Keep in mind, this application is only going to be used on an intranet so the only reason for needing any encryption at all would be if someone was to gain access to the client's network they couldn't packet sniff for the user's passwords (which are being MD5 hashed and stored in the server's database).  Any thoughts on this would be helpful.  

I have considered strictly using the built in Windows authentication but it's unclear to me just what the client would have to do in order to configure each terminal to gain access to the server.  Keep in mind, this really needs to be simple for the customer to install and configure on their own.  At the moment all that is needed is to enter the server's IP address in each terminal once the application is installed and I would like to keep it that way.  Of coarse each user has to have an account setup with a username and password but that's it and that's pretty simple.  I'm not looking for identity verification with this certificate, just encryption so self-signed is fine.  Any thoughts or advice about this would be helpful.  

FYI: currently working with .net 4 on VS2010 RC

Thanks,
Casey
thesnomanAsked:
Who is Participating?
 
thesnomanConnect With a Mentor Author Commented:
Well as it turns out, it wasn't to bad to generate a self-signed certificate with .Net and store it so I'm just going down that route.  

Something I ran into and wanted to pass along to others related to the following error:

"Additional information: Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was '127.0.0.1' but the remote endpoint provided DNS claim [MyCertificateCommonName]. If this is a legitimate remote endpoint, you can fix the problem by explicitly specifying DNS identity [MyCertificateCommonName] as the Identity property of EndpointAddress when creating channel proxy."

Everything I found on the internet pointed to changing the following value in the client's app.config file:

 <identity>  
    <dns value="localhost" />
</identity>

TO

 <identity>  
    <dns value="[MyCertificateCommonName]" />
</identity>

However there is something that I didn't find mentioned.  When you are overriding the Endpoint Address on the client at runtime as I am it seems to override the identity as well.  Therefor you have to set the identity at runtime as my code snippet shows.  Anyway I now have a single certificate, self-generated, and installed by the server at runtime and I am using message level encryption (over nettcp) with no certificate installed on the client.  So hopefully my findings will help someone else out in the future.

As for my original idea, I still do not know if it's possible to create and use a certificate in memory, however since I found that storing a certificate is not bad at all I don't think it matters.






Private WithEvents _ConnectionClient As Service1Client
Private _Context = New InstanceContext(New IServiceCallbackHandler())

Public Sub ConfigureClient()
  Me._ConnectionClient = New Service1Client(_Context)
  Dim epIdent As EndpointIdentity = New DnsEndpointIdentity("[MyCertificateCommonName]")
  Dim newUri As Uri = New Uri("net.tcp://127.0.0.1:8081/Design-Time_Addresses/LocalServer/IService1/")
  Me._ConnectionClient.Endpoint.Address = New EndpointAddress(newUri, epIdent)
End Sub

Open in new window

0
 
CodeCruiserCommented:
If you would generate the certificate on the server side dynamically, how would the client decrypt the communication?

Following links may help

http://msdn.microsoft.com/en-us/library/ms730301.aspx

http://msdn.microsoft.com/en-us/library/ms732362.aspx

0
 
thesnomanAuthor Commented:
Hi CodeCruiser.
Well assuming that WCF uses the Public Key/Private Key model, like SSL does then the service would need to pass the public key off to the client during the initial handshake.  Obviously with SSL the client never needs a certificate to communicate securely with the server.  One thing that doesn't look possible to me at this point is transport security with SSL over nettcp, but I could be mistaken.

At the moment I am just generating and storing the certificate on the services' first run.  Then I check to ensure the certificate is found and assign it to my service using SetCertificate.  I'm still having trouble getting the client to connect, looks like some sort of a DNS identity problem but I am making progress.

I'm still learning this stuff and so far the security portion of it is pretty daunting so please have patience with me.

Thanks,
Casey
0
All Courses

From novice to tech pro — start learning today.