Problems using .Net RSACryptoServiceProvider for XML Digital Signatures in a Shared Web Hosting Environment

Last Updated on Tuesday, 14 February 2012 01:14 Written by nishad.chitrasen Tuesday, 14 February 2012 01:14

If you are a software developer looking for a free and fairly easy way to license your software for trials and purchasing then this article is for you.

A while ago I found this very useful article about digitally signing xml files:

Using XML Digital Signatures for Application Licensing

http://www.codeproject.com/KB/security/xmldsiglic.aspx

These code samples are for the .Net environment and therefore require a Windows host to run on. The link above has all the information you need to create your own encryption keys and use them for adding a ‘signature’ to your xml license files. When your application reads the license file on start up to check and see if the ‘expired’ date has passed, for example, you can also be sure that the license file has not been tampered with by verifying its digital signature.

The code worked great on the home development sever, but when the digital signing was moved to the shared server environment, it ran into some obstacles that are apparently by design in the shared server environment: namely the use of encryption is tightly controlled for security reasons.

The first error encountered said the code needed more ‘permission’ to access the ‘Key Container’, (see below, Error 1).  Sarthi support graciously accommodated me with the required permission to get passed this first hurdle. But then a second error was encountered, (see below, Error 2). Not being fluent in .Net server admin or encryption, it was by no means obvious what the remedy for this second error was, or even if there was one; and the results Google returned including Microsoft’s own information didn’t shed much light.

The first error seemed reasonable and was quickly resolved by Sarthi support, but the second error, ‘cannot find the file specified’, made less sense as the code was not accessing any files. The ‘file’ being referred to in the error message is apparently the ‘machine key store’ and every attempt to use a private key results in this error; Even using ‘System.Security.Cryptography.RSA.FromXmlString,’ which does not explicitly refer to the machine key store, generates the same error. For the purpose of this article, suffice it to say it’s a restriction related to server security, or at least server efficiency.

The good news is there is available, again at codeproject.com, a simple and easy workaround that requires no extra server permissions and is not dependent on any special server settings. Thanks again to the gurus who provide us great source code samples on the internet, here is the link:

Using RSA Public Key Encryption in a Shared Web Hosting Environment

http://www.codeproject.com/KB/security/EZRSA.aspx

This link provides source code to completely replace the use of .Net’s System.Security.Cryptography.RSA.FromXmlString, which allows use of cryptography without using the system’s machine key store. (In the code from the first link above, for the part that uses a private key to do the digital signing, replace the use of CspProviderFlags.UseMachineKeyStore with FromXmlString.)

The replacement class, EZRSA, works exactly the same as the .Net version for the FromXmlString method, after you read the comments and make a few tweaks to the source code: i.e. 1.KeySize should return keyLen * 8, 2. inherit from ‘RSA’ rather than ‘AsymmetricAlgorithm’, 3. Add a couple of overridable methods, (see the comments.) In my case I also had to change the default constructor from 512 to 1024 to use the keys I had already been using, e.g. EZRSA csp = new EZRSA(1024);

Somehow the link to this excellent workaround avoided me the first few web searches, maybe it will be a little easier to find now. Thanks again to the all the orignal coders!

Error 1

[SecurityException: Request for the permission of type  'System.Security.Permissions.KeyContainerPermission, mscorlib, Version=2.0.0.0,  Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]  System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark&  stackMark, Boolean isPermSet) +0 System.Security.CodeAccessPermission.Demand() +58  System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters  parameters) +240 System.Security.Cryptography.RSA.FromXmlString(String xmlString)


Error 2
The second error from the online version is:
CryptographicException: The system cannot find the file specified.  System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean  randomKeyContainer) +7712542 System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters  parameters) +258   System.Security.Cryptography.RSA.FromXmlString(String xmlString) +470  SignXml.SignXml.Page_Load(Object sender, EventArgs e) +417

How to Get More Detailed Errors from IIS

Last Updated on Tuesday, 14 February 2012 01:10 Written by nishad.chitrasen Tuesday, 14 February 2012 01:10

On the new version of WebSitePanel, you can easily do this through the control panel! Click HERE to find out how!

Related documents:

  1. Error Reading Web Site Information – WebSitePanel or DotNetPanel

Say you work on your website on whatever language that may be, for this example, I’ll use ASP.

Then you encounter an error message, for this example, say the dreaded 500 – Internal server error (picture 1).

500_internal_server_error

picture 1

So you sit there thinking “Ok, thanks! That doesn’t give me a clue on what my problem is!

Lets fix that, shell we?

Edit your web.config file, inside the <system.webServer> section put this line in:

<httpErrors errorMode=”Detailed” />

See (picture 2) for an example.

500_internal_server_error_web_config_detailed_errors

picture 2

IMPORTANT: If you are using ASP .NET, you also need to add the following inside the <system.web> tags of your web.config (at the end of the tag). If there is no <system.web>, simply create a starting and ending tag before <system.webserver> like so:

<system.web>
<customErrors defaultRedirect=”errors.aspx” mode=”Off” />
</system.web>

IMPORTANT: If you are using ASP, you may need to turn on errors being sent to the browser. This is done by adding the following tag right before the end system.web tag.

<system.web>
<asp scriptErrorSentToBrowser=”true” />
</system.web>

Now we that in place and saved, try to browse your website and in my case, this is what I now saw:

500_internal_server_error_detailed_error

picture 3

Ok! Now I know that I forgot my include file … how silly of me!

FYI, that code was bound to break on purpose, since I didn’t really have those includes… this code was just for the purpose of this demonstration and is noted for you, below:

<%@ Language=VBScript %>

<% Option Explicit %>

<!– #include virtual = “/adovbs.inc” –>

<!– #include virtual = “/conn.asp” –>

<!doctype html public “-//w3c//dtd html 3.2//en”>

<html>

<head>

<title>(Type a title for your page here)</title>

</head>

<body bgcolor=”#ffffff” text=”#000000″ link=”#0000ff” vlink=”#800080″ alink=”#ff0000″>

<%

Dim conn,R,SQL,RecsAffected

Set conn=Server.CreateObject(“ADODB.Connection”)

conn.Mode=adModeReadWrite

conn.ConnectionString = aConnectionString

conn.Open

Securing mojoPortal with a Custom Machine Key

Last Updated on Tuesday, 14 February 2012 12:56 Written by nishad.chitrasen Tuesday, 14 February 2012 12:56

Problem1September 17, 2010 Microsoft issued a Security Advisory

Vulnerability in ASP.NET

This not the first time, nor will it be the last time.

Who is responsible for the security of your Web Site?

You are!

MojoPortal has a lot of documentation on Securing MojoPortal.  They also have documentation on How and Why You Should Generate a Custom Machine Key.

However, in this blog post I am going to walk you through making a Custom machine key in crystal clear detail with all the pictures included.

First make sure you are logged in as administrator and go to the Administration Menu.  If your screen looks like this and Security Advisor says “Needs Attention!” click Learn More.  If it does not, stop reading for now and you are done.

2-Problems

In Administration, Click on the Security Advisor Link and the screen may look similar to this but without my yellow warnings.

clear-text

The mojoPortal Security advisor checks two ASP.NET vulnerable areas in your mojoPortal installation.

1. Use a Custom Machine Key – This Blog.

2. Securing The File System – covered in my previous blog here.

If you are still with me here, I am assuming that the first check “Verify that a custom machine key is being used” also says “Danger – Not Secure”

VERY IMPORTANT – The first thing you should do is to check what your Web Sites Security Password Format is set to:

Go to Administration Menu > Site Settings, click on the Security Tab and on the Main sub tab check the “Password format” setting.

In order to safely change the machine key your Security Password format should be set to “Clear Text in db” OR “Hashed in db” as below.

encrypted

If it is set to “Encrypted in db” like this (below) change it to “Clear Text in db” and click “Save” before you continue.

web-config

Why is this so important?  If we change the machine key with the passwords encrypted, we will not be able to login to our mojoPortal site after we change the machine key.  This would be very bad.  If you have lots of users and data in your mojoPortal databases and this scares you then you had better backup your database before you continue.

Ok.  Now with your Security Password format set and saved to “Clear Text in db” OR “Hashed in db” we can go back to Administration Menu > Security Advisor.

In the editable text area, note the first 4 characters after <machineKey=

Then click the link “Generate a new Key”.  Now wait and watch those first 4 characters after <machineKey=

and when they change you will now have a new key to enter into your sites web.config file which is a text file in the root of your mojoPortal Web Site.  Select and copy all the text in the text box from  the first left arrow < right to and including the ending right arrow >

Using ftp, copy your Web Sites web.config file to your local computer and open the file in notepad or whatever text editor you use.

Somewhere around line 675 of your web.config file, it will look something like this.

all-ok

Do not delete or over-write the existing/old machine key yet.  Move the comment tag –> below the key first like I have above in the first highlighted section.  I like to keep the old key until I know for sure that the new key works and allows me to login to the Web Site successfully.

The bottom highlighted line above is where I pasted in my new machine key.  Make sure the new pasted key is complete including the closing arrow tag >

After this is done, saved the web.config file and ftp it back to your mojoPortal Web Site.

*** Keep this new web.config and new machine key FOREVER! What I mean is…  If you ever upgrade mojoPortal (and you will) the web.config file in the upgrade will need this new machine key change too.  Keep this new machine key in a safe place.  It is the key to your database login forever.  IF you lose it you may be locked out of your mojoPortal CMS

VERY IMPORTANT – Access your Web Site and test logging in. If you can not login, you have done something wrong.  Review the steps above and if all fails, restore your old commented machine key line in your web.config file.

When you have finished testing your login, go go back to Administration Menu > Security Advisor and it will look like this.

If you want more security (and you should) you should now go back to Administration Menu > Site Settings, click on the Security Tab and on the Main sub tab change the “Password format”.  With a new secure machine key working for you, it is now safe to set this to “Encrypted in db” and click save.

That’s it.  You’re done.

Nishad