Introduction
How to do cryptography with X509 certificates.
Background
There is a great article on cryptography and I had to use certificates so I created a class around the functions from
http://www.codeproject.com/Articles/10877/Public-Key-RSA-Encryption-in-C-NET.
Using the code
Create a class project with C# and paste the code and build, after that you can add the reference to the project and you will be able to encrypt and decrypt using a X509 certificate.
#region
using System;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
#endregion
namespace CertificateCrypto
{
public class X509Cryptography
{
public readonly X509Certificate2 _CertFile;
public readonly bool _FOaep;
public X509Cryptography(X509Certificate2 certFile, bool fOAEP)
{
if (certFile != null) _CertFile = certFile;
else throw new SystemException("Certificate is null");
_FOaep = fOAEP;
}
public X509Cryptography(X509Certificate2 certFile)
{
if (certFile != null) _CertFile = certFile;
else throw new SystemException("Certificate is null");
_FOaep = false;
}
public static byte[] ReadStream(Stream input)
{
using (var ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
#region Encryption
public string EncryptStringTest(string inputString)
{
var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PublicKey.Key;
int keySize = rsaCryptoServiceProvider.KeySize/8;
byte[] bytes = Encoding.UTF32.GetBytes(inputString);
int maxLength = keySize - 42;
int dataLength = bytes.Length;
int iterations = dataLength/maxLength;
var stringBuilder = new StringBuilder();
for (int i = 0; i <= iterations; i++)
{
var tempBytes = new byte[
(dataLength - maxLength*i > maxLength)
? maxLength
: dataLength - maxLength*i];
Buffer.BlockCopy(bytes, maxLength*i, tempBytes, 0,
tempBytes.Length);
byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, _FOaep);
Array.Reverse(encryptedBytes);
stringBuilder.Append(Convert.ToBase64String(encryptedBytes));
}
return stringBuilder.ToString();
}
public string DecryptStringTest(string inputString)
{
var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PrivateKey;
int keySize = rsaCryptoServiceProvider.KeySize/8;
int base64BlockSize = ((keySize/8)%3 != 0) ? (((keySize/8)/3)*4) + 4 : ((keySize/8)/3)*4;
int iterations = inputString.Length/base64BlockSize;
var arrayList = new ArrayList();
for (int i = 0; i < iterations; i++)
{
byte[] encryptedBytes = Convert.FromBase64String(
inputString.Substring(base64BlockSize*i, base64BlockSize));
Array.Reverse(encryptedBytes);
arrayList.AddRange(rsaCryptoServiceProvider.Decrypt(encryptedBytes, _FOaep));
}
return Encoding.UTF32.GetString(arrayList.ToArray(Type.GetType("System.Byte")) as byte[]);
}
public string EncryptString(string inputString)
{
try
{
var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PublicKey.Key;
int keySize = rsaCryptoServiceProvider.KeySize/8;
byte[] bytes = Encoding.UTF32.GetBytes(inputString);
int maxLength = keySize - 42;
int dataLength = bytes.Length;
int iterations = dataLength/maxLength;
var stringBuilder = new StringBuilder();
for (int i = 0; i <= iterations; i++)
{
var tempBytes = new byte[
(dataLength - maxLength*i > maxLength)
? maxLength
: dataLength - maxLength*i];
Buffer.BlockCopy(bytes, maxLength*i, tempBytes, 0,
tempBytes.Length);
byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes,
true);
Array.Reverse(encryptedBytes);
stringBuilder.Append(Convert.ToBase64String(encryptedBytes));
}
return stringBuilder.ToString();
}
catch (Exception ex)
{
throw new SystemException(ex.Message);
}
}
public string DecryptString(string inputString)
{
try
{
var rsaCryptoServiceProvider
= (RSACryptoServiceProvider) _CertFile.PrivateKey;
int dwKeySize = rsaCryptoServiceProvider.KeySize;
int base64BlockSize = ((dwKeySize/8)%3 != 0)
? (((dwKeySize/8)/3)*4) + 4
: ((dwKeySize/8)/3)*4;
int iterations = inputString.Length/base64BlockSize;
var arrayList = new ArrayList();
for (int i = 0; i < iterations; i++)
{
byte[] encryptedBytes = Convert.FromBase64String(
inputString.Substring(base64BlockSize*i, base64BlockSize));
Array.Reverse(encryptedBytes);
arrayList.AddRange(rsaCryptoServiceProvider.Decrypt(
encryptedBytes, true));
}
return Encoding.ASCII.GetString(arrayList.ToArray(
Type.GetType("System.Byte")) as byte[]);
}
catch (Exception ex)
{
throw new SystemException(ex.Message);
}
}
#endregion
}
}
Points of Interest
It was a bit difficult to find the exact code I needed but one I went through the article
http://www.codeproject.com/Articles/10877/Public-Key-RSA-Encryption-in-C-NET
and asymetric encryption 101 it became clear.