Introduction
File encryption/decryption is an old topic, and there are kinds of methods/algorithms/tools in the world.
In this tip, I’m going to demonstrate how to use Microsoft .NET Cryptography library to encrypt and decrypt file, and also how to add signature to prevent files from being tampered.
Background
Generally speaking, there are 2 kinds of encryption algorithms——symmetric-key algorithm and asymmetric-key algorithm.
For symmetric-key algorithm, the same cryptographic key is used for both encryption and decryption, in comparison to asymmetric-key algorithm symmetric-key algorithm like AES is usually high speed and low RAM requirements, but because it’s the same key for both encryption and decryption, it’s a big problem of key transport from encryption side (sender) to decryption side (receiver).
For asymmetric-key algorithm, it requires two separate keys, one of which is secret (or private) and one of which is public. Although different, the two parts of this key pair are mathematically linked. The public key is used to encrypt plaintext or to verify a digital signature; whereas the private key is used to decrypt ciphertext or to create a digital signature, comparing to symmetric-key algorithm, asymmetric-key algorithm does not have the problem of key transport, but it is computationally costly compared with symmetric key algorithm.
The way to make both ends meet is using the 2 algorithms in combination:
- Data receiver creates the key pairs of asymmetric-key algorithm, and publishes the public key to sender.
- Sender uses symmetric-key algorithm to encrypt data, and uses asymmetric-key algorithm to encrypt that symmetric key with receiver’s public key.
- Receiver uses its private key to decrypt the symmetric key, and then decrypt data with the symmetric key.
Here symmetric-key algorithm is only used to encrypt the symmetric key, computationally cost is negligible.
Yes, that’s the way SSL works!
For our file encryption tool, AES (A symmetric-key algorithm) is used to encrypt file data, and RSA (an asymmetric cryptography standard) is used to encrypt AES key.
Using the Code
This project is built with Visual Studio 2012, all core codes are placed in Encipher.cs.
Generate RSA Key Pair
public static void GenerateRSAKeyPair(out string publicKey, out string privateKey)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
publicKey = rsa.ToXmlString(false);
privateKey = rsa.ToXmlString(true);
}
GenerateRSAKeyPair
utilizes RSACrytoServiceProvide
to create RSA key pairs, the generated keys are in the format of XML string, this method could be triggered by UI menu Tool->Generate Key Pair, to save the generated key pair into two XML files, privateKey.xml and publicKey.xml.
File Encryption
private static void EncryptFile(string plainFilePath,
string encryptedFilePath,
byte[] key,
byte[] iv)
{
using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
{
aes.KeySize = 128;
aes.Key = key;
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (FileStream plain = File.Open(plainFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (FileStream encrypted = File.Open(encryptedFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (CryptoStream cs = new CryptoStream(encrypted, encryptor, CryptoStreamMode.Write))
{
plain.CopyTo(cs);
}
}
}
}
}
EncryptFile
uses AesCryptoServiceProvider
to encrypt a plain file, Encrypt
is the consumer of EncryptFile
.
public static string Encrypt(string plainFilePath,
string encryptedFilePath,
string manifestFilePath,
string rsaKey)
{
byte[] signatureKey = GenerateRandom(64);
byte[] encryptionKey = GenerateRandom(16);
byte[] encryptionIV = GenerateRandom(16);
EncryptFile(plainFilePath, encryptedFilePath, encryptionKey, encryptionIV);
byte[] signature = CalculateSignature(encryptedFilePath, signatureKey);
CreateManifest(signature, signatureKey, encryptionKey, encryptionIV, rsaKey, manifestFilePath);
return CreateEncryptionInfoXml(signatureKey, encryptionKey, encryptionIV);
}
Those codes are pretty straight-forward, Encrypt
generates the one-time pad AES key and IV for encrypting file, also generates the signature key for calculating file signature.
Then it calls EncryptFile
to perform file encryption.
Finally, it encrypts the AES key and signatureKey
with the public key passed-in (rsaKey), and saves all that encrypted key information into an XML file called manifest file.
The manifest file will be used by decryption logic later.
The encryption logic could be triggered by Encrypt
button.
But before doing that, make sure you have imported a public key in setting dialog.
The encrypted file will be named as xxxx.encrypted placed in the same folder of the plain file, the manifest file xxxx.manifest.xml will be generated at the same time.
File Decryption
Decryption is simply the inverse process of encryption logic.
It uses decrypts ciphertext in manifest XML file with its RSA private key to get the AES key generated in encryption process, and then decrypts file with the AES key.
As for UI, make sure to switch the tool perspective to file decryption view by File->Switch.
Besides, select the file to be encrypted, it needs to specify the RSA private key, and the manifest file generated in the encryption process.
The decrypted file will be named xxxx.decrypted, placed in the same location of encrypted one.
Method bt_decrypt_Click()
is the point from which more details can be found.
History
- October 29, 2014: Initial post