In one of my projects, we had requirement
of encrypting and decrypting files using the standard PGP (Pretty good
privacy) algorithm.
Approach
There are no
built-in implementations of PGP encryption/decryption algorithms in .NET. Hence
we used a third party open source DLL (BouncyCastle.Crypto.dll) from Bouncy-Castle that provided the
implementation of PGP algorithm. This DLL was used after taking a formal
approval from Tools-Group.
The DLL provides
basic classes and methods for performing encryption/decryption which are a bit
complex to understand and requires a lot of plumbing code to be usable in the
project.
Hence we created
a wrapper class around this DLL which provides two simple methods for
encryption and decryption. This class has all the plumbing code required for using
the PGP encryption/decryption functionality.
PGP
Encryption/Decryption
The PGP encryption
algorithm works on the basic principle of public-private key pairs. The public
key is with the person who wants to encrypt the file. The private key is with
the person who wants to decrypt the file. While the public key is shared with
everyone, the private key is kept secret.
Implementation
We need to
first add the BouncyCastle.Crypto.dll in our project.
We created a class (PGPEncryptDecrypt.cs) which acted as a
wrapper around the BouncyCastle.Crypto.dll.
The class performs following tasks:-
- Encrypt
a file using PGP
- Decrypt
a file using PGP
PGP Keys
Both public and private keys are
kept in separate files with “.pgp” extension. It is a simple plain text file
where key is stored in encrypted format. These keys can be generated using
various tools available in market viz GPG, WSFTP Professional, PGP etc. In our project we have used WSFTP
Professional to generate PGP keys.
While generating PGP keys, the
tools ask for following information:-
- Name
- Email
- Pass-phrase
To use the private key file, we
need a pass-phrase. This pass-phrase ensures that even if someone gets hold on
the private key file, they will not be able to decrypt the target file unless
they know the pass-phrase as well.
Sample Code
Encrypt file
The encryption of file is doing by
calling function “Encrypt” in the
wrapper class. This function takes following input parameters –
- filePath – Path of file to be
encrypted along with file name
- publicKeyFile – Path of public key
file.
- pathToSaveFile – Path where
encrypted file should be saved
The encrypted file is saved with a
“.pgp” extension.
/// <summary>
/// Method to encrypt a file using a public key file
/// </summary>
/// <param name=”filePath”>The path of the file to be
encrypted</param>
/// <param name=”publicKeyFile”>The path of the
public key file</param>
/// <param name=”pathToSaveFile”>The path where
encrypted file will be saved</param>
public string Encrypt(string filePath, string
publicKeyFile, string pathToSaveFile)
{
Stream keyIn,
fos;
keyIn = File.OpenRead(publicKeyFile);
string[]
fileSplit = filePath.Split(‘\\’);
string fileName =
fileSplit[fileSplit.Length – 1];
fos = File.Create(pathToSaveFile
+ fileName + “.pgp”);
EncryptFile(fos,
filePath, ReadPublicKey(keyIn), true, true);
keyIn.Close();
fos.Close();
return fileName +
“.pgp”;
}
Decrypt file
The decryption of file is done
using the “Decrypt” function in
wrapper class. This function takes following input parameters:-
- filePath – Path of file to be
decrypted along with file name.
- privateKeyFile – Path of private
key file.
- passphrase – The secret
pass-phrase which will be used to open the private key.
- pathToSaveFile – Path where
decrypted file should be saved.
/// <summary>
/// Method to decrypt a file using a private key and a pass-phrase
/// </summary>
/// <param name="filePath">Path of file to
be decrypted</param>
/// <param name="privateKeyFile">Path of private
key file</param>
/// <param name="passPhrase">Pass phrase to
decrypt file </param>
/// <param name="pathToSaveFile">Path to store
the decrypted file</param>
public string Decrypt(string filePath, string
privateKeyFile, string passPhrase, string pathToSaveFile)
{
Stream fin = File.OpenRead(filePath);
Stream keyIn = File.OpenRead(privateKeyFile);
string decryptedFileName
= DecryptFile(fin,
keyIn,
passPhrase.ToCharArray(),
new FileInfo(filePath).Name
+ ".out",
pathToSaveFile);
fin.Close();
keyIn.Close();
return
decryptedFileName;
}
Sample function calls
How to call Encrypt function:-
PGPEncryptDecrypt pgp = new PGPEncryptDecrypt();
string filePath = @"C:\SampleFile.doc";
string pathToSaveFile = @"C:\";
string encryptedFileName = string.Empty;
string publicKeyFile = @"C:\PGPKeys\PublicKey.pgp";
encryptedFileName = pgp.Encrypt(filePath, publicKeyFile,
pathToSaveFile);
How to call Decrypt function
PGPEncryptDecrypt pgp = new PGPEncryptDecrypt();
string encryptedfilePath = @"C:\SampleFile.doc.pgp";
string pathToSaveFile = @"C:\";
string decryptedFileName = string.Empty;
string privateKeyFile = @"C:\PGPKeys\PrivateKey.pgp";
string passPhrase = "<Sample pass
phrase>";
encryptedFileName = pgp.Decrypt(encryptedfilePath,
privateKeyFile, passPhrase, pathToSaveFile);
Advantages
The class file wraps the
intricacies of BouncyCastle.Crypto.dll and provides simple interface which can
be used to perform PGP encryption/decryption.
2 comments:
Where is EncryptFile method?
Please provide the complete source code?
Post a Comment