using System; using System.Security.Cryptography; using System.Text; using System.IO; using System.Configuration; using System.Collections; namespace .ChrisDonnan.Cryptography.Asymmetric { ////// Summary description for Class1. /// public class CryptoUtils { RSACryptoServiceProvider rsaPublic; RSACryptoServiceProvider rsaPrivate; string publicKeyPath; string privateKeyPath; /// /// on instantiation, the PublicKeyPath and PrivateKeyPath are pulled from the ConfigurationSettings.AppSettings /// by default. If they are not found here, they default to "PublicKey.xml" and "PrivateKey.xml" respectively. /// public CryptoUtils() { publicKeyPath = ConfigurationSettings.AppSettings["RSA.PublicKeyPath"]; privateKeyPath = ConfigurationSettings.AppSettings["RSA.PrivateKeyPath"]; if(publicKeyPath==null) PublicKeyPath = "PublicKey.xml"; if(privateKeyPath==null) PrivateKeyPath = "PrivateKey.xml"; } /// /// used if you want to change Public key /// public void ReloadPublicKey() { if(rsaPublic!=null) { rsaPublic.Clear(); rsaPublic = null; } rsaPublic = new RSACryptoServiceProvider(); rsaPublic.FromXmlString(GetTextFileAsString(publicKeyPath)); } /// /// used if you want to change Public key /// /// public void ReloadPublicKey(string publicKeyFileName) { PublicKeyPath = publicKeyFileName; ReloadPublicKey(); } /// /// used if you want to change Private key /// public void ReloadPrivateKey() { if(rsaPrivate!=null) { rsaPrivate.Clear(); rsaPrivate = null; } rsaPrivate = new RSACryptoServiceProvider(); rsaPrivate.FromXmlString(GetTextFileAsString(privateKeyPath)); } /// /// used if you want to change Private key /// /// public void ReloadPrivateKey(string privateKeyFileName) { PrivateKeyPath = privateKeyFileName; ReloadPrivateKey(); } /// /// saves a key pair to the supplied files /// /// a file name (path/path/file.ext etc, or file.ext) /// a file name (path/path/file.ext etc, or file.ext) /// between 384 (48 byte) and 16384 (2048 byte) public static void GenerateKeyPair(int keySize, string publicKeyFileName, string privateKeyFileName) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize); string publicKey = rsa.ToXmlString(false); string privateKey = rsa.ToXmlString(true); SaveTextFile(publicKey,publicKeyFileName); SaveTextFile(privateKey,privateKeyFileName); } /// /// Main encryption method for RSA Encryption /// This method uses the Public Key /// kyey size between 384 (48 byte) and 16384 (2048 byte) /// (key size bytes - 11 = byte blobk size) /// Modulus size - 11. (11 bytes is the minimum padding possible.) /// /// /// Base64 Encrypted data public string RSAEncrypt(string dataToEncrypt) { if(dataToEncrypt==null) return string.Empty; if(rsaPublic==null) rsaPublic= new RSACryptoServiceProvider(); rsaPublic.FromXmlString(GetTextFileAsString(publicKeyPath)); int keySizeInBytes = rsaPublic.KeySize/8; int blockSize = keySizeInBytes - 11; int iterations = 0; if(dataToEncrypt.Length % blockSize != 0) { iterations = ((int)dataToEncrypt.Length/blockSize) + 1 ; } else { iterations = (int)dataToEncrypt.Length/blockSize; } byte[] allEncryptedBytes = new byte[iterations*keySizeInBytes]; char[] dataToEncryptAsChars = dataToEncrypt.ToCharArray(); int index = 0; int counter = 0; for(;counter < iterations; index+=blockSize, ++counter) { int doneSoFar = counter * blockSize; int endIndex = 0; //if 1st iteration and data smaller than block if(counter == 0 && dataToEncryptAsChars.Length<blockSize) { endIndex = dataToEncryptAsChars.Length; } else { //final block if(counter==iterations-1) { endIndex = dataToEncryptAsChars.Length % blockSize; } else { endIndex = blockSize; } } byte[] buffer = ASCIIEncoding.ASCII.GetBytes(dataToEncryptAsChars,index,endIndex); byte[] encryptedBytes = rsaPublic.Encrypt(buffer,false); Array.Copy(encryptedBytes,0,allEncryptedBytes,counter*keySizeInBytes,keySizeInBytes); } return Convert.ToBase64String( allEncryptedBytes ); } ////// Override for dealing with a supplied publicKeyPath /// /// /// /// public string RSAEncrypt(string dataToEncrypt, string publicKeyPath) { PublicKeyPath = publicKeyPath; return RSAEncrypt(dataToEncrypt); } /// /// This method uses the private key /// /// Base64 RSA Encrypted data /// public string RSADecrypt(string dataToDecrypt) { if(dataToDecrypt==null) return string.Empty; if(rsaPrivate==null) rsaPrivate= new RSACryptoServiceProvider(); rsaPrivate.FromXmlString(GetTextFileAsString(privateKeyPath)); int keySizeInBytes = rsaPublic.KeySize/8; int blockSize = keySizeInBytes - 11; int iterations = 0; byte[] dataToDecryptBuffer = Convert.FromBase64String(dataToDecrypt); if(dataToDecryptBuffer.Length % keySizeInBytes != 0) throw new ApplicationException("malformed data to decrypt"); iterations = dataToDecryptBuffer.Length/ keySizeInBytes; int counter = 0; Queue q = new Queue(); for(;counter < iterations; ++counter) { int doneSoFar = counter * keySizeInBytes; byte[] buffer = new byte[keySizeInBytes]; Array.Copy(dataToDecryptBuffer,counter*keySizeInBytes,buffer,0,keySizeInBytes); byte[] decryptedBytes = rsaPrivate.Decrypt(buffer,false); q.Enqueue(decryptedBytes); } int byteCount = 0; foreach(byte[] b in q) { byteCount+=b.Length; } byte[] allDecryptedBytes = new byte[byteCount]; counter = 0; foreach(byte[] b in q) { //last one if(counter==iterations-1) { Array.Copy(b,0,allDecryptedBytes,allDecryptedBytes.Length-b.Length,b.Length); } else { Array.Copy(b,0,allDecryptedBytes,counter*blockSize,blockSize); } ++counter; } return ASCIIEncoding.ASCII.GetString( allDecryptedBytes ); } /// /// Override for dealing with a supplied privateKeyPath /// /// /// /// public string RSADecrypt(string dataToDecrypt, string privateKeyPath) { PrivateKeyPath = privateKeyPath; return RSADecrypt(dataToDecrypt); } /// /// path to XML persisted RSA key; the public or distributable key /// public string PublicKeyPath { set {publicKeyPath = value;} } /// /// path to XML persisted RSA key; the private or non-distributable key /// public string PrivateKeyPath { set {privateKeyPath = value;} } static void SaveTextFile(string text, string file) { StreamWriter writer = new StreamWriter (new FileStream(file, FileMode.Create)); writer.Write(text); writer.Close(); } static byte[] BinaryFileAsBytes(string fileName) { FileStream fs = File.OpenRead(fileName); BinaryReader br = new BinaryReader(fs); return br.ReadBytes((int)fs.Length); } static string GetTextFileAsString(string fileName) { return Encoding.ASCII.GetString(BinaryFileAsBytes(fileName)); } } }
Chris Donnan : Programming – Brooklyn Style
software, trading, family, fun
More useful code – lets oversimplify asymmetric encryption for general convenience . . .
Posted c#, coding on Monday, June 23rd, 2003.
Posted c#, coding on Monday, June 23rd, 2003.
You can leave a response, or trackback from your own site.
ReturnCode.cs – helper class of the day :) Use it :)
Posted c# on Tuesday, June 17th, 2003.
Posted c# on Tuesday, June 17th, 2003.
using System; namespace Utils { /////////////////////////////////////////////////////////////////////////// ////// Class to encapsulate the result of a method call. /// public class ReturnCode { private int number = 0; private string message; private DateTime created; private object resultObject; /// /// /// public int Number { get { return number; } set { number = value; } } /// /// /// public string Message { get { return message; } set { message = value; } } /// /// /// public DateTime Created { get { return created; } set { created = value; } } /// /// /// public object ResultObject { get { return resultObject; } set { resultObject = value; } } /// /// /// /// /// public ReturnCode( int number, string message ) { this.Number = number; this.Message = message; this.Created = DateTime.Now; } /// /// /// /// public override string ToString() { return "ReturnCode : " + this.Number.ToString() + ", " + this.Message + " at " + this.Created.ToString("G") + " : ResultObject.ToString() = '"+ ((ResultObject==null)?"null":ResultObject.ToString() ) +"'"; } } }
You can leave a response, or trackback from your own site.
1st post – off topic completely
Posted Family on Monday, June 16th, 2003.
Posted Family on Monday, June 16th, 2003.
Happy fathers day dads !
(Myself included, today is my 1st!)
Today, no code – odd. Spent the day with my 11 month old son playing
We could all use more days like today.
You can leave a response, or trackback from your own site.
From saturday – new Interactive Brokers C#/.Net interface
Posted Interop, c#, trading on Monday, June 16th, 2003.
Posted Interop, c#, trading on Monday, June 16th, 2003.
Spent the day fiddling with this InteractiveBrokersHost.cs . Good ActiveX Wrapper for a good direct access broker (with great comissions). Took a bit of ‘jimmying’ to get it straight, but it is there. I never was much of an activeX visual component guy, and now in .Net I will reiterate my disaproval. It does however meet an end, next is to make a socket based implementation to the brokerage so I can eliminate the activeX layer and compile on mono.
L8,
Chris
You can leave a response, or trackback from your own site.
