6
comments
Wednesday, April 01, 2009
Beside from the security we squeeze from appliance such as firewall and antivirus, it is a must for our applications to have a second layer of defense. Most often than not you already have several company-wide applications that are interconnected to each other. If you have remote offices, your data will be transmitted over broadband network or internet but how sure are you that each of the application is only accepting data from valid sender? For example, a billing software at remote office that transmits payment confirmation to the financial system located at your head office. Fortunately for .NET developers we can make use of digital certificates. Using digital signatures, we can implement the following security check on our example scenario:
Where:
App 1 - Billing Software located at the remote office
App 2 - Financial System located at the head office
1. App 1 sign the unique message using digital certificate private key. For example: "POST TRANSACTION"
2. App 1 send the digital signature to App 2 (via web service or ftp file)
3. App 2 receives the digital signature and verify command by using digital certificate public key
Let's put it in C# Code:
1. Sign the text or message using digital certificate's private key. You can have set of commands that are expected by the client application.
private byte[] SignCertificate(string text)
{
// Open certificate store of current user
X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
my.Open(OpenFlags.ReadOnly);
// Look for the certificate with specific subject
RSACryptoServiceProvider csp = null;
foreach (X509Certificate2 cert in my.Certificates)
{
if (cert.Subject.Contains("CN=WINGROUP\\micwein"))
{
// retrieve private key
csp = (RSACryptoServiceProvider)cert.PrivateKey;
}
}
if (csp == null)
{
throw new Exception("Valid certificate was not found");
}
// Hash the data
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
// Sign the hash
return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
}
2. On your server/listener application, validate the digital signature if correct
private bool VerifyCommand(string text, byte[] signature, string certPath)
{
// Load the certificate file to use to verify the signature from a file
// If using web service or ASP.NET, use: X509Certificate2 cert = new X509Certificate2(Request.ClientCertificate.Certificate);
X509Certificate2 cert = new X509Certificate2(certPath);
// Get public key
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key;
// Hash the text, the text is the expected command by the client application.
// Remember hased data cannot be unhash. It is irreversable
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
// Verify the signature with the hash
return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);
}
Here a sample code on how to call VerifyCommand:
//Use the mycert.cer certificate to verify signature and validate it against the allowed commands
if (VerifyCommand("POST TRANSACTION", signature, @"C:\mycert.cer")) //POST TRANS
{
MessageBox.Show("POST command received from remote client....");
}
else if (VerifyCommand("CANCEL TRANSACTION", signature, @"C:\mycert.cer")) //CANCEL TRANS
{
MessageBox.Show("Cancel command received from remote client....");
}
else if (VerifyCommand("RETRIEVE TRANSACTION", signature, @"C:\mycert.cer")) //RETRIEVE TRANS
{
MessageBox.Show("RETRIEVE Transaction received from remote client....");
}
else
{
MessageBox.Show("Signature is not valid");
}
You can pass the signature to client using web service or FTP. You can download the complete sample source code of this article from here
Continue Reading...



