Monday, July 18, 2011

Implementing PGP File Encryption in ASP.Net/C# Using GnuPG

I was recently asked to implement PGP encryption for a file before sending it to a vendor. In performing my research, I found GnuPG to be the easiest solution to understand as well as posing the least amount of risk for implementation. The great thing about GnuPG is that you can download it and the instructions are easy to follow for encrypting files.

Unfortunately, I also found are some challenges during the implementation. The existing documentation on the web is also confusing and is old. This post is an attempt to update the existing documentation to 2009, provide a working coded example, and give a quick and easy roadmap for implementing PGP in an ASP.Net project.

Step 1 – Download and install GnuPG (GPG)

The main GnuPG page is http://www.gnupg.org. The Windows download can be found here. The version I refer to in this post is GnuPG 1.4.10b.




Installing the GnuPG software is easy as it uses a standard installer.




Note: Be careful when installing the application on the server. Choose a Windows account that is generic to installations. There is a mistake in the installation process where important application data is installed in the Application Data directory of the account performing the installation.




You can find the files by installing GnuPG on your local machine and then looking inC:\Documents and Settings\[%Windows User Name%]\Application Data\GnuPG. Several key files are installed there and you will need to reference this directory from the ASP.Net code. This is the biggest ‘gotcha’ for the entire process.




Update (2011-01-12): For 64-bit servers, the directory is C:\Users\[user name]\AppData\Roaming\gnupg
Step 2 – Learn GPG

An excellent introduction to GPG has been written by Brendan Kidwell and can be found here.

You will find excellent instructions for installation and use in Windows and Linux. Pay special attention to the GPG Cheat Sheet and make sure you successfully encrypt and decrypt files from the command line before proceeding with coding.

You will need to install any public keys needed for encryption before running the code, as well as understanding how to retrieve the name of the name of the key (using –list-keys) before running the C# below.

Step 3 – Implement the PGP Object

Following is the code that I use to encrypt files. It is heavily indebted to an article at the Code Project on decrypting files by Kurt Mang.

using System;
using System.Diagnostics;
using System.IO;
using System.Security;

/// 
/// File encryption wrapper.  Executes GNU PGP as described here:
/// http://www.glump.net/howto/gpg_intro
/// And downloaded from here:
/// http://www.gnupg.org/download/index.en.html#auto-ref-2
/// 
public class PGP
{
/// 
/// Path to the PGP software
/// 
string _pgpPath = @"C:\Program Files\GNU\GnuPG\gpg.exe";

/// 
/// The path to the PGP file can be changed (if needed) 
/// or executed
/// 
public string PgpPath {
get { return _pgpPath; }
set { _pgpPath = value; }
}
/// 
/// The home directory argument in GnuPG
/// 
string _homeDir;
/// 
/// The location of the PubRing and SecRing files
/// 
public string HomeDirectory {
get { return _homeDir; }
set { _homeDir = value; }
}
/// 
/// Public constructor stores the home directory argument
/// 
public PGP(string homeDirectory) {
HomeDirectory = homeDirectory;
}

/// 
/// Encrypts the file
/// 
/// Name of the encryption file
/// Source file to be encrypted
/// Destination file (after encryption)
public bool Encrypt(string keyName, string fileFrom, string fileTo) {

/// File info
FileInfo fi = new FileInfo(fileFrom);
if(!fi.Exists) {
throw new Exception("Missing file.  Cannot find the file to encrypt.");
}

/// Cannot encrypt a file if it already exists
if(File.Exists(fileTo)) {
throw new Exception("Cannot encrypt file.  File already exists");
}

/// Confirm the existence of the PGP software
if(!File.Exists(PgpPath)) {
throw new Exception("Cannot find PGP software.");
}

/// Turn off all windows for the process
ProcessStartInfo s = new ProcessStartInfo("cmd.exe");
s.CreateNoWindow = true;
s.UseShellExecute = false;
s.RedirectStandardInput = true;
s.RedirectStandardOutput = true;
s.RedirectStandardError = true;
s.WorkingDirectory = fi.DirectoryName;

/// Execute the process and wait for it to exit.  
/// NOTE: IF THE PROCESS CRASHES, it will freeze
bool processExited = false;

using(Process p = Process.Start(s)) {
/// Build the encryption arguments
string recipient = " -r \"" + keyName + "\"";
string output = " -o \"" + fileTo + "\"";
string encrypt = " -e \"" + fileFrom + "\"";
string homedir = " --homedir \"" + HomeDirectory + "\"";
string cmd = "\"" + PgpPath + "\"" + homedir + recipient + output + encrypt;

p.StandardInput.WriteLine(cmd);
p.StandardInput.Flush();
p.StandardInput.Close();
processExited = p.WaitForExit(3500);
p.Close();
}
return processExited;
}

}



A couple of things should be noted about this object:
The constructor takes a HomeDirectory argument. This is the Application Settings directory where the GPG application files have been installed.
Obviously the Windows account that runs the ASP.Net code needs to have access to the executable as well as the ability to run executables and create files.
The code checks for the existence of the GPG executable, the source file and the destination file. The reason is that the application can hang without throwing an exception if anything goes wrong.

Reference : http://rlieving.blogspot.com/2009/10/implementing-pgp-file-encryption-in.html

Sunday, July 17, 2011

SNR and Attenuation

As an ADSL n00b I wanted to understand how the technology works and how to get the most out of it. In essence if you want to improve speed and increase stability you need to familiarise yourself with SNR (signal to noise ratio) and attenuation. Many ADSL-routers will provide you with those stats.
SNR or Signal to Noise Ratio:
Describes the ratio of usable data-signals on your line. You can associate the "signal" with the data traveling across your ADSL-line and the "noise" as the unwanted interference affecting the signal. The higher the number the better for this measurement. In some instances interleaving can help raise the noise margin to an acceptable level.
6dB or below is bad and will experience no synch or intermittent synch problems
7dB-10dB is fair but does not leave much room for variances in conditions
11dB-20dB is good with little or no synch problems
20dB-28dB is excellent
29dB or above is outstanding
If your SNR is below 12dB you are pretty much screwed and will not get a consistent level of ADSL-service. You could try to convince Telkom to rewire the cabling - but this is unlikely to happen.
Attenuation:
Is the reduction in signal strength on your phone line. In ADSL this may be reported as "loop loss" and is the natural deterioration of the ADSL signal over distance from the exchange. Attenuation is normally directly linked to the length of your line. Copper is traditionally used in the local loop and the higher gauge of copper will give the best signal, however some lines may have some aluminium or aluminium joints on the line which will increase resistance... as will oxidisation of joints. The lower the dB the better for this measurement.
20dB and below is outstanding
20dB-30dB is excellent
30dB-40dB is very good
40dB-50dB is good
50dB-60dB is poor and may experience connectivity issues
60dB or above is bad and will experience connectivity issues
The standard signal attenuation spread for a given speed is somewhere in the region of 25-30dB for ADSL1 speeds (if we had ADSL2/2+ this would be).
The following guide (distance vs. attenuation vs speed) gives you an guestimate what you can achieve:
<1km should be 23-24Mbit (nice speed, but doesn't it bug you that Telkom people walk through your bedroom?)
1.0km = 13.81dB = 23Mbit
1.5km = 20.7dB = 21Mbit
2.0km = 27.6dB = 18Mbit
2.5km = 34.5dB = 13Mbit
3.0km = 41.4dB = 8Mbit
3.5km = 48.3dB = 6Mbit
4.0km = 56dB = 4Mbit
4.5km = 62.1dB = 3Mbit
5.0km = 69dB = 2Mbit
>5.0km (you are pretty much poked --- sorry for you)
You will not be able to fix attenuation (unless you relocate straight next to the exchange). You will however be able to influence Telkom or your ISPs - use tooling such as MRTG to measure your variances and log incidents against them. It is unlikely that they will move the exchange closer, but you could combat SNR (check your wiring, climb into the manhole and see if your underground wire is of the cheap kind etc).