Retired Microsoft Blog disclaimer

This directory is a mirror of retired "Decrypt My World" MSDN blog and is provided as is. All posting authorship and copyrights belong to respective authors.
Original URL: https://blogs.msdn.microsoft.com/alejacma/2008/10/23/how-to-generate-key-pairs-encrypt-and-decrypt-data-with-net-c/
Post name: How to generate key pairs, encrypt and decrypt data with .NET (C#)
Original author: Alejandro Campos Magencio
Posting date: 2008-10-23T05:03:00+00:00


Hi all,


The other day a colleague of mine asked me if I hada .NET version of the C++ sample inHow to generate key pairs, encrypt and decrypt data with CryptoAPIpost. C++ sample calls CryptoAPI directly (and you know we can do the same thing in .NET through P/Invoke), but the idea was to use System.Security classes in order to get a pure .NET solution. The answer is yes, I have such sample, and here it is:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace EncryptDecrypt
{
class Program
{
// Main
static void Main(string[] args)
{
if ((args.Length == 3) && (args[0].Equals("k")))
{
// Generate a new key pair
Keys(args[1], args[2]);

}
else if ((args.Length == 4) && (args[0].Equals("e")))
{
// Encrypt a file
Encrypt(args[1], args[2], args[3]);

}
else if ((args.Length == 4) && (args[0].Equals("d")))
{
// Decrypt a file
Decrypt(args[1], args[2], args[3]);
}
else {
// Show usage
Console.WriteLine("Usage:");
Console.WriteLine(" - New key pair: EncryptDecrypt k public_key_file private_key_file");
Console.WriteLine(" - Encrypt: EncryptDecrypt e public_key_file plain_file encrypted_file");
Console.WriteLine(" - Decrypt: EncryptDecrypt d private_key_file encrypted_file plain_file");
}

// Exit
Console.WriteLine("\n<< Press any key to continue >>");
Console.ReadKey();
return;

} // Main

// Generate a new key pair
static void Keys(string publicKeyFileName, string privateKeyFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamWriter publicKeyFile = null;
StreamWriter privateKeyFile = null;
string publicKey = "";
string privateKey = "";

try
{
// Create a new key pair on target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
cspParams.Flags = CspProviderFlags.UseArchivableKey;
cspParams.KeyNumber = (int)KeyNumber.Exchange;
rsaProvider = new RSACryptoServiceProvider(cspParams);

// Export public key
publicKey = rsaProvider.ToXmlString(false);

// Write public key to file
publicKeyFile = File.CreateText(publicKeyFileName);
publicKeyFile.Write(publicKey);

// Export private/public key pair
privateKey = rsaProvider.ToXmlString(true);

// Write private/public key pair to file
privateKeyFile = File.CreateText(privateKeyFileName);
privateKeyFile.Write(privateKey);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception generating a new key pair! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (publicKeyFile != null)
{
publicKeyFile.Close();
}
if (privateKeyFile != null)
{
privateKeyFile.Close();
}
}

} // Keys

// Encrypt a file
static void Encrypt(string publicKeyFileName, string plainFileName, string encryptedFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamReader publicKeyFile = null;
StreamReader plainFile = null;
FileStream encryptedFile = null;
string publicKeyText = "";
string plainText = "";
byte[] plainBytes = null;
byte[] encryptedBytes = null;

try
{
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
rsaProvider = new RSACryptoServiceProvider(cspParams);

// Read public key from file
publicKeyFile = File.OpenText(publicKeyFileName);
publicKeyText = publicKeyFile.ReadToEnd();

// Import public key
rsaProvider.FromXmlString(publicKeyText);

// Read plain text from file
plainFile = File.OpenText(plainFileName);
plainText = plainFile.ReadToEnd();

// Encrypt plain text
plainBytes = Encoding.Unicode.GetBytes(plainText);
encryptedBytes = rsaProvider.Encrypt(plainBytes, false);

// Write encrypted text to file
encryptedFile = File.Create(encryptedFileName);
encryptedFile.Write(encryptedBytes, 0, encryptedBytes.Length);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception encrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (publicKeyFile != null)
{
publicKeyFile.Close();
}
if (plainFile != null)
{
plainFile.Close();
}
if (encryptedFile != null)
{
encryptedFile.Close();
}
}

} // Encrypt

// Decrypt a file
static void Decrypt(string privateKeyFileName, string encryptedFileName, string plainFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamReader privateKeyFile = null;
FileStream encryptedFile = null;
StreamWriter plainFile = null;
string privateKeyText = "";
string plainText = "";
byte[] encryptedBytes = null;
byte[] plainBytes = null;

try
{
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
rsaProvider = new RSACryptoServiceProvider(cspParams);

// Read private/public key pair from file
privateKeyFile = File.OpenText(privateKeyFileName);
privateKeyText = privateKeyFile.ReadToEnd();

// Import private/public key pair
rsaProvider.FromXmlString(privateKeyText);

// Read encrypted text from file
encryptedFile = File.OpenRead(encryptedFileName);
encryptedBytes = new byte[encryptedFile.Length];
encryptedFile.Read(encryptedBytes, 0, (int)encryptedFile.Length);

// Decrypt text
plainBytes = rsaProvider.Decrypt(encryptedBytes, false);

// Write decrypted text to file
plainFile = File.CreateText(plainFileName);
plainText = Encoding.Unicode.GetString(plainBytes);
plainFile.Write(plainText);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception decrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (privateKeyFile != null)
{
privateKeyFile.Close();
}
if (encryptedFile != null)
{
encryptedFile.Close();
}
if (plainFile != null)
{
plainFile.Close();
}
}

} // Decrypt
}
}


If you compare both samples you will see that .NET simplifies the task a lot. But sometimes we won't be able to do withSystem.Security classes exactly the same we can do with CryptoAPI. So don't forget about the API just yet!


I hope this helps.


Kind regards,



Alex (Alejandro Campos Magencio)


Share this article:

Comments:

Comments are closed.