Secure RESTful WCF Service with SHA-256 hashing

This is an old draft I found, perhaps it is useful if you’re trying to do SHA-256. If not, let me know, I might be able to help you out. Azure Storage supports secure access of resources without logon. It involves hashing the query part of the URL and then signing that hash. I’ve implemented this at my workplace┬áin the following steps:

  • Create a web project for a WCF service.
  • Update the .svc file by adding (this makes everything work without configuration, found this here):

Factory="System.ServiceModel.Activation.WebServiceHostFactory"

  • Add the following attribute to your interface method:

[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "?p0={parameter0}&p1={parameter1}&sig={signature}")]

  • Create a method like (please note that parameter names match those specified in the WebInvoke attribute and that they are all string type):

Stream MyMethod(string parameter0, string parameter1, string signature);

  • In the implementation of MyMethod verify the signature with the following function:

bool ValidSignature(string customerID, string signature, params string[] toSignArguments)
{
var certificate = FindCertificate(customerID);
if (certificate == null) {
return false;
}
const string TERMINATOR = "\n";
var toSign = string.Join(TERMINATOR, toSignArguments) + TERMINATOR;
var oldProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;
using (var newProvider = new RSACryptoServiceProvider())
{
newProvider.ImportCspBlob(oldProvider.ExportCspBlob(false));
return newProvider.VerifyData(Encoding.UTF8.GetBytes(toSign), "SHA256", Convert.FromBase64String(signature));
}
}

The trick is to create a new provider instead of the default one you get when loading the key. The default is connected to the wrong library that doesn’t support SHA-256.