|
using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace Core.Cryptography
{
public static class CryptHelper
{
private static readonly string _storageSlot = "__KeyManagerAsymmetricKeys";
private static readonly object _storageLock = new object();
static CryptHelper()
{
Dictionary<string, RSACryptoServiceProvider> list = new Dictionary<string, RSACryptoServiceProvider>();
AppDomain.CurrentDomain.SetData(_storageSlot, list);
}
public static WrappedData AsymmetricEncrypt(RSACryptoServiceProvider csp, string plainText)
{
// Generate the temporary Session Key
RijndaelManaged symmetric = new RijndaelManaged();
symmetric.GenerateIV();
symmetric.GenerateKey();
// encrypt the data using the temporary session Key
byte[] inputBuffer = Encoding.Unicode.GetBytes(plainText);
byte[] encryptedData = symmetric.CreateEncryptor().TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);
// encrypt the session key using the Asymmetric CSP
byte[] encryptedKeyData = csp.Encrypt(symmetric.Key, true);
// Create the wrapped data structure
WrappedData wrappedData = new WrappedData();
wrappedData.EncryptedData = Convert.ToBase64String(encryptedData);
wrappedData.EncryptedKey = Convert.ToBase64String(encryptedKeyData);
wrappedData.IV = Convert.ToBase64String(symmetric.IV);
return wrappedData;
}
public static WrappedData AsymmetricEncrypt(string certificateThumb, string plainText)
{
RSACryptoServiceProvider csp = GetAsymmetricKey(certificateThumb, false);
WrappedData wrappedData = AsymmetricEncrypt(csp, plainText);
wrappedData.Certificate = certificateThumb;
return wrappedData;
}
public static string AsymmetricDecrypt(WrappedData wrappedData)
{
// Get the Asymmetric key that matches the wrapped data certificate
RSACryptoServiceProvider csp = GetAsymmetricKey(wrappedData.Certificate, true);
// decrypt the temporary Symmetric Key
byte[] clearKey = csp.Decrypt(Convert.FromBase64String(wrappedData.EncryptedKey), true);
byte[] iv = Convert.FromBase64String(wrappedData.IV);
byte[] encryptedData = Convert.FromBase64String(wrappedData.EncryptedData);
// Setup the tetm
RijndaelManaged symmetric = new RijndaelManaged();
byte[] clearData = symmetric.CreateDecryptor(clearKey, iv).TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return Encoding.Unicode.GetString(clearData);
}
private static RSACryptoServiceProvider GetAsymmetricKey(string thumb, bool includePrivate )
{
Dictionary<string, RSACryptoServiceProvider> list =
AppDomain.CurrentDomain.GetData(_storageSlot) as Dictionary<string, RSACryptoServiceProvider>;
if (list == null)
{
throw new ApplicationException("Invalid State: The key storage is not setup");
}
RSACryptoServiceProvider csp = null;
if (list.ContainsKey(thumb) == false)
{
lock (_storageLock)
{
if (csp == null)
{
csp = LoadKey(thumb, includePrivate);
list[thumb] = csp;
}
}
}
else
{
csp = list[thumb];
}
return csp;
}
public static string CreateSessionKeyString()
{
RijndaelManaged csp = new RijndaelManaged();
csp.GenerateIV();
csp.GenerateKey();
String xml = string.Format(
"<RijndaelManagedKey format='B64'><Key>{0}</Key><IV>{1}</IV></RijndaelManagedKey>",
System.Convert.ToBase64String( csp.Key ),
System.Convert.ToBase64String( csp.IV ) );
return xml;
}
public static RijndaelManaged GetSessionKey(string sessionKeyString)
{
System.Xml.XmlDocument document = new System.Xml.XmlDocument();
document.LoadXml(sessionKeyString);
System.Xml.XmlNode node = document.SelectSingleNode("/RijndaelManagedKey");
System.Xml.XmlAttribute attribute = node.Attributes["format"];
if (attribute != null && attribute.Value != "B64")
throw new ApplicationException("Unknown key format " + attribute.Value);
byte[] key = null;
byte[] iv = null;
foreach (System.Xml.XmlNode child in node.ChildNodes)
{
switch (child.Name)
{
case "Key":
key = Convert.FromBase64String(child.InnerText);
break;
case "IV" :
iv = Convert.FromBase64String(child.InnerText);
break;
}
}
RijndaelManaged csp = new RijndaelManaged();
csp.Key = key;
csp.IV = iv;
return csp;
}
private static RSACryptoServiceProvider LoadKey(string thumb, bool includePrivate)
{
System.Security.Cryptography.X509Certificates.X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
string certThumb = thumb.Replace(" ", string.Empty);
foreach (X509Certificate2 certificate in store.Certificates)
{
if (certThumb.ToLower() == certificate.Thumbprint.ToLower())
{
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
if (includePrivate == true)
{
if (certificate.HasPrivateKey == false)
throw new ArgumentException("Private key for specified key is not available");
csp.FromXmlString(certificate.PrivateKey.ToXmlString(true));
}
else
{
csp.FromXmlString(certificate.PublicKey.Key.ToXmlString(false));
}
return csp;
}
}
throw new ApplicationException("Specified certificate was not found on this machine");
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.