Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *
- * http://csharpcodewhisperer.blogspot.com
- *
- *
- * Made using SharpDevelop
- */
- using System;
- using System.IO;
- using System.Security.Cryptography;
- namespace CryptKeeper
- {
- public class RSAWrapper
- {
- CspParameters cspp;
- RSACryptoServiceProvider rsa;
- string KeyContainerName = string.Empty;
- public bool IsClosed = true;
- public RSAWrapper()
- {
- }
- ~RSAWrapper()
- {
- if(!IsClosed) {
- rsa.Clear();
- }
- }
- public RSAWrapper(string ContainerName)
- {
- OpenKeyContainer(ContainerName);
- }
- public void SetKey(string ContainerName)
- {
- OpenKeyContainer(ContainerName);
- }
- private void OpenKeyContainer(string ContainerName)
- {
- if(string.IsNullOrEmpty(ContainerName)) {
- return;
- }
- if(!IsClosed) {
- Close();
- }
- cspp = new CspParameters();
- cspp.KeyContainerName = ContainerName;
- cspp.Flags |= CspProviderFlags.UseMachineKeyStore;
- rsa = new RSACryptoServiceProvider(cspp);
- rsa.PersistKeyInCsp = true;
- IsClosed = false;
- }
- public void PersistKey(bool PersistKeyContainer)
- {
- rsa.PersistKeyInCsp = PersistKeyContainer;
- }
- public void Close()
- {
- if(!IsClosed) {
- rsa.Clear();
- }
- rsa = null;
- cspp = null;
- IsClosed = true;
- }
- public void ExportKeyAsFile(string FileName,bool IncludePrivateKey=false)
- {
- if(IsClosed) {
- return;
- }
- Directory.CreateDirectory(Path.GetDirectoryName(FileName));
- using(StreamWriter streamWriter = new StreamWriter(Path.GetFullPath(FileName),false))
- {
- streamWriter.Write(rsa.ToXmlString(IncludePrivateKey));
- streamWriter.Flush();
- }
- }
- public void ImportKeyFromFile(string FileName)
- {
- if(!IsClosed) {
- Close();
- }
- if(!File.Exists(FileName)) {
- return;
- }
- string xmlString = string.Empty;
- using(StreamReader streamReader = new StreamReader(FileName))
- {
- xmlString = streamReader.ReadToEnd();
- }
- cspp = new CspParameters();
- rsa = new RSACryptoServiceProvider(cspp);
- rsa.FromXmlString(xmlString);
- }
- public CspKeyContainerInfo GetKeyContainerInfo()
- {
- if(IsClosed) {
- return new CspKeyContainerInfo(new CspParameters());
- }
- return rsa.CspKeyContainerInfo;
- }
- public bool PublicOnly()
- {
- if(IsClosed) {
- return false;
- }
- return rsa.PublicOnly;
- }
- public int KeySize()
- {
- return rsa.KeySize;
- }
- public string KeyExchangeAlgorithm()
- {
- return rsa.KeyExchangeAlgorithm.ToString();
- }
- public string SignatureAlgorithm()
- {
- return rsa.SignatureAlgorithm.ToString();
- }
- public void EncryptFile(string FileName,string FileName_Output="")
- {
- if(IsClosed) { return; }
- // Create instance of Rijndael for
- // symetric encryption of the data.
- RijndaelManaged rjndl = new RijndaelManaged();
- rjndl.KeySize = 256;
- rjndl.BlockSize = 256;
- rjndl.Mode = CipherMode.CBC;
- ICryptoTransform transform = rjndl.CreateEncryptor();
- // Use RSACryptoServiceProvider to
- // enrypt the Rijndael key.
- // rsa is previously instantiated:
- // rsa = new RSACryptoServiceProvider(cspp);
- byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false);
- // Create byte arrays to contain
- // the length values of the key and IV.
- byte[] LenK = new byte[4];
- byte[] LenIV = new byte[4];
- int lKey = keyEncrypted.Length;
- LenK = BitConverter.GetBytes(lKey);
- int lIV = rjndl.IV.Length;
- LenIV = BitConverter.GetBytes(lIV);
- byte[] seperator = {0,0,0,0};
- // Write the following to the FileStream
- // for the encrypted file (outFs):
- // - length of the key
- // - length of the IV
- // - ecrypted key
- // - the IV
- // - the encrypted cipher content
- int startFileName = FileName.LastIndexOf("\\") + 1;
- string outFile = FileName_Output;
- if(string.IsNullOrWhiteSpace(outFile))
- {
- // Change the file's extension to ".enc"
- outFile = Path.ChangeExtension(FileName,".enc");
- Directory.CreateDirectory(Path.GetDirectoryName(outFile));
- }
- using (FileStream outFs = new FileStream(outFile, FileMode.Create))
- {
- outFs.Write(LenK, 0, 4);
- outFs.Write(LenIV, 0, 4);
- outFs.Write(keyEncrypted, 0, lKey);
- outFs.Write(rjndl.IV, 0, lIV);
- //outFs.Write(seperator, 0, 4);
- //outFs.Write(rjndl.Key, 0 , 4);
- // Now write the cipher text using
- // a CryptoStream for encrypting.
- using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
- {
- // By encrypting a chunk at
- // a time, you can save memory
- // and accommodate large files.
- int count = 0;
- int offset = 0;
- // blockSizeBytes can be any arbitrary size.
- int blockSizeBytes = rjndl.BlockSize / 8;
- byte[] data = new byte[blockSizeBytes];
- int bytesRead = 0;
- using (FileStream inFs = new FileStream(Path.GetFullPath(FileName), FileMode.Open))
- {
- do
- {
- count = inFs.Read(data, 0, blockSizeBytes);
- offset += count;
- outStreamEncrypted.Write(data, 0, count);
- bytesRead += blockSizeBytes;
- }
- while (count > 0);
- inFs.Close();
- }
- outStreamEncrypted.FlushFinalBlock();
- }
- outFs.Flush();
- }
- rjndl.Clear();
- }
- public void DecryptFile(string FileName,string FileName_Output="")
- {
- if(IsClosed) {
- return;
- }
- if(!File.Exists(FileName)) {
- return;
- }
- // Create instance of Rijndael for
- // symetric decryption of the data.
- RijndaelManaged rjndl = new RijndaelManaged();
- rjndl.KeySize = 256;
- rjndl.BlockSize = 256;
- rjndl.Mode = CipherMode.CBC;
- // Create byte arrays to get the length of the encrypted key and IV.
- // These values were stored as 4 bytes each at the beginning of the encrypted package.
- byte[] LenK = new byte[4];
- byte[] LenIV = new byte[4];
- string outFile = FileName_Output;
- if(string.IsNullOrWhiteSpace(outFile))
- {
- // Consruct the file name from the encrypted file.
- outFile = Path.ChangeExtension(FileName,".dec");
- Directory.CreateDirectory(Path.GetDirectoryName(outFile));
- }
- // Use FileStream objects to read the encrypted
- // file (inFs) and save the decrypted file (outFs).
- using (FileStream inFs = new FileStream(Path.GetFullPath(FileName), FileMode.Open))
- {
- inFs.Seek(0, SeekOrigin.Begin);
- inFs.Seek(0, SeekOrigin.Begin);
- inFs.Read(LenK, 0, 3);
- inFs.Seek(4, SeekOrigin.Begin);
- inFs.Read(LenIV, 0, 3);
- // Convert the lengths to integer values.
- int lenK = BitConverter.ToInt32(LenK, 0);
- int lenIV = BitConverter.ToInt32(LenIV, 0);
- // Determine the start postition of the
- // ciphter text (startC) and its length(lenC).
- int startC = lenK + lenIV + 8;
- int lenC = (int)inFs.Length - startC;
- // Create the byte arrays for the
- // encrypted Rijndael key, the IV, and the cipher text.
- byte[] KeyEncrypted = new byte[lenK];
- byte[] IV = new byte[lenIV];
- // Extract the key and IV starting from index 8,
- // after the length values.
- inFs.Seek(8, SeekOrigin.Begin);
- inFs.Read(KeyEncrypted, 0, lenK);
- inFs.Seek(8 + lenK, SeekOrigin.Begin);
- inFs.Read(IV, 0, lenIV);
- // Use RSACryptoServiceProvider to decrypt the Rijndael key.
- byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);
- // Decrypt the key.
- ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV);
- // Decrypt the cipher text from from the FileSteam of the encrypted
- // file (inFs) into the FileStream for the decrypted file (outFs).
- using (FileStream outFs = new FileStream(outFile, FileMode.Create))
- {
- int count = 0;
- int offset = 0;
- // blockSizeBytes can be any arbitrary size.
- int blockSizeBytes = rjndl.BlockSize / 8;
- byte[] data = new byte[blockSizeBytes];
- // By decrypting one chunk at time, you can
- // save memory and accommodate large files.
- // Begin
- inFs.Seek(startC, SeekOrigin.Begin);
- using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
- {
- do {
- count = inFs.Read(data, 0, blockSizeBytes);
- offset += count;
- outStreamDecrypted.Write(data, 0, count);
- } while (count > 0);
- outStreamDecrypted.FlushFinalBlock();
- }
- outFs.Flush();
- }
- }
- rjndl.Clear();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement