Advertisement
BurningBunny

CryptKeeper RSAWrapper class

Jun 23rd, 2013
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.50 KB | None | 0 0
  1. /*
  2.  *
  3.  * http://csharpcodewhisperer.blogspot.com
  4.  *
  5.  *
  6.  * Made using SharpDevelop
  7.  */
  8. using System;
  9. using System.IO;
  10. using System.Security.Cryptography;
  11.  
  12. namespace CryptKeeper
  13. {
  14.     public class RSAWrapper
  15.     {
  16.         CspParameters cspp;
  17.         RSACryptoServiceProvider rsa;
  18.        
  19.         string KeyContainerName = string.Empty;
  20.         public bool IsClosed = true;
  21.        
  22.         public RSAWrapper()
  23.         {
  24.         }
  25.        
  26.         ~RSAWrapper()
  27.         {
  28.             if(!IsClosed) {
  29.                 rsa.Clear();
  30.             }
  31.         }
  32.        
  33.        
  34.         public RSAWrapper(string ContainerName)
  35.         {
  36.             OpenKeyContainer(ContainerName);
  37.         }
  38.        
  39.         public void SetKey(string ContainerName)
  40.         {
  41.             OpenKeyContainer(ContainerName);
  42.         }
  43.        
  44.         private void OpenKeyContainer(string ContainerName)
  45.         {
  46.             if(string.IsNullOrEmpty(ContainerName)) {
  47.                 return;
  48.             }
  49.            
  50.             if(!IsClosed) {
  51.                 Close();
  52.             }
  53.            
  54.             cspp = new CspParameters();
  55.             cspp.KeyContainerName = ContainerName;
  56.             cspp.Flags |= CspProviderFlags.UseMachineKeyStore;
  57.             rsa = new RSACryptoServiceProvider(cspp);
  58.             rsa.PersistKeyInCsp = true;
  59.            
  60.             IsClosed = false;
  61.         }
  62.        
  63.         public void PersistKey(bool PersistKeyContainer)
  64.         {
  65.             rsa.PersistKeyInCsp = PersistKeyContainer;
  66.         }
  67.        
  68.         public void Close()
  69.         {
  70.             if(!IsClosed) {
  71.                 rsa.Clear();
  72.             }
  73.             rsa = null;
  74.             cspp = null;
  75.             IsClosed = true;
  76.         }
  77.        
  78.        
  79.         public void ExportKeyAsFile(string FileName,bool IncludePrivateKey=false)
  80.         {
  81.             if(IsClosed) {
  82.                 return;
  83.             }
  84.            
  85.             Directory.CreateDirectory(Path.GetDirectoryName(FileName));
  86.             using(StreamWriter streamWriter = new StreamWriter(Path.GetFullPath(FileName),false))
  87.             {
  88.                 streamWriter.Write(rsa.ToXmlString(IncludePrivateKey));
  89.                 streamWriter.Flush();
  90.             }
  91.         }
  92.        
  93.         public void ImportKeyFromFile(string FileName)
  94.         {
  95.             if(!IsClosed) {
  96.                 Close();
  97.             }
  98.             if(!File.Exists(FileName)) {
  99.                 return;
  100.             }
  101.                        
  102.             string xmlString = string.Empty;
  103.             using(StreamReader streamReader = new StreamReader(FileName))
  104.             {
  105.                 xmlString = streamReader.ReadToEnd();
  106.             }
  107.            
  108.             cspp = new CspParameters();
  109.             rsa = new RSACryptoServiceProvider(cspp);
  110.             rsa.FromXmlString(xmlString);
  111.         }
  112.        
  113.         public CspKeyContainerInfo GetKeyContainerInfo()
  114.         {
  115.             if(IsClosed) {
  116.                 return new CspKeyContainerInfo(new CspParameters());
  117.             }
  118.             return rsa.CspKeyContainerInfo;
  119.         }
  120.        
  121.         public bool PublicOnly()
  122.         {
  123.             if(IsClosed) {
  124.                 return false;
  125.             }
  126.             return rsa.PublicOnly;
  127.         }
  128.        
  129.         public int KeySize()
  130.         {
  131.             return rsa.KeySize;
  132.         }
  133.        
  134.         public string KeyExchangeAlgorithm()
  135.         {
  136.             return rsa.KeyExchangeAlgorithm.ToString();
  137.         }
  138.        
  139.         public string SignatureAlgorithm()
  140.         {
  141.             return rsa.SignatureAlgorithm.ToString();
  142.         }
  143.        
  144.         public void EncryptFile(string FileName,string FileName_Output="")
  145.         {
  146.             if(IsClosed) { return; }
  147.            
  148.             // Create instance of Rijndael for
  149.             // symetric encryption of the data.
  150.             RijndaelManaged rjndl = new RijndaelManaged();
  151.             rjndl.KeySize = 256;
  152.             rjndl.BlockSize = 256;
  153.             rjndl.Mode = CipherMode.CBC;
  154.             ICryptoTransform transform = rjndl.CreateEncryptor();
  155.            
  156.             // Use RSACryptoServiceProvider to
  157.             // enrypt the Rijndael key.
  158.             // rsa is previously instantiated:
  159.             //    rsa = new RSACryptoServiceProvider(cspp);
  160.             byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false);
  161.            
  162.             // Create byte arrays to contain
  163.             // the length values of the key and IV.
  164.             byte[] LenK = new byte[4];
  165.             byte[] LenIV = new byte[4];
  166.  
  167.             int lKey = keyEncrypted.Length;
  168.             LenK = BitConverter.GetBytes(lKey);
  169.             int lIV = rjndl.IV.Length;
  170.             LenIV = BitConverter.GetBytes(lIV);
  171.            
  172.             byte[] seperator = {0,0,0,0};
  173.            
  174.             // Write the following to the FileStream
  175.             // for the encrypted file (outFs):
  176.             // - length of the key
  177.             // - length of the IV
  178.             // - ecrypted key
  179.             // - the IV
  180.             // - the encrypted cipher content
  181.            
  182.             int startFileName = FileName.LastIndexOf("\\") + 1;
  183.            
  184.             string outFile = FileName_Output;
  185.             if(string.IsNullOrWhiteSpace(outFile))
  186.             {
  187.                 // Change the file's extension to ".enc"
  188.                 outFile = Path.ChangeExtension(FileName,".enc");
  189.                 Directory.CreateDirectory(Path.GetDirectoryName(outFile));
  190.             }
  191.  
  192.             using (FileStream outFs = new FileStream(outFile, FileMode.Create))
  193.             {
  194.  
  195.                 outFs.Write(LenK, 0, 4);
  196.                 outFs.Write(LenIV, 0, 4);
  197.                 outFs.Write(keyEncrypted, 0, lKey);
  198.                 outFs.Write(rjndl.IV, 0, lIV);
  199.                 //outFs.Write(seperator, 0, 4);
  200.                 //outFs.Write(rjndl.Key, 0 , 4);
  201.                
  202.                 // Now write the cipher text using
  203.                 // a CryptoStream for encrypting.
  204.                 using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
  205.                 {
  206.  
  207.                     // By encrypting a chunk at
  208.                     // a time, you can save memory
  209.                     // and accommodate large files.
  210.                     int count = 0;
  211.                     int offset = 0;
  212.  
  213.                     // blockSizeBytes can be any arbitrary size.
  214.                     int blockSizeBytes = rjndl.BlockSize / 8;
  215.                     byte[] data = new byte[blockSizeBytes];
  216.                     int bytesRead = 0;
  217.                    
  218.                     using (FileStream inFs = new FileStream(Path.GetFullPath(FileName), FileMode.Open))
  219.                     {
  220.                         do
  221.                         {
  222.                             count = inFs.Read(data, 0, blockSizeBytes);
  223.                             offset += count;
  224.                             outStreamEncrypted.Write(data, 0, count);
  225.                             bytesRead += blockSizeBytes;
  226.                         }
  227.                         while (count > 0);
  228.                         inFs.Close();
  229.                     }
  230.                     outStreamEncrypted.FlushFinalBlock();
  231.                 }
  232.                 outFs.Flush();
  233.             }
  234.             rjndl.Clear();
  235.         }
  236.        
  237.         public void DecryptFile(string FileName,string FileName_Output="")
  238.         {
  239.             if(IsClosed) {
  240.                 return;
  241.             }
  242.             if(!File.Exists(FileName)) {
  243.                 return;
  244.             }
  245.            
  246.             // Create instance of Rijndael for
  247.             // symetric decryption of the data.
  248.             RijndaelManaged rjndl = new RijndaelManaged();
  249.             rjndl.KeySize = 256;
  250.             rjndl.BlockSize = 256;
  251.             rjndl.Mode = CipherMode.CBC;
  252.  
  253.             // Create byte arrays to get the length of the encrypted key and IV.
  254.             // These values were stored as 4 bytes each at the beginning of the encrypted package.
  255.             byte[] LenK = new byte[4];
  256.             byte[] LenIV = new byte[4];
  257.  
  258.             string outFile = FileName_Output;
  259.             if(string.IsNullOrWhiteSpace(outFile))
  260.             {
  261.                 // Consruct the file name from the encrypted file.
  262.                 outFile = Path.ChangeExtension(FileName,".dec");
  263.                 Directory.CreateDirectory(Path.GetDirectoryName(outFile));
  264.             }
  265.  
  266.             // Use FileStream objects to read the encrypted
  267.             // file (inFs) and save the decrypted file (outFs).
  268.             using (FileStream inFs = new FileStream(Path.GetFullPath(FileName), FileMode.Open))
  269.             {
  270.  
  271.                 inFs.Seek(0, SeekOrigin.Begin);
  272.                 inFs.Seek(0, SeekOrigin.Begin);
  273.                 inFs.Read(LenK, 0, 3);
  274.                 inFs.Seek(4, SeekOrigin.Begin);
  275.                 inFs.Read(LenIV, 0, 3);
  276.  
  277.                 // Convert the lengths to integer values.
  278.                 int lenK = BitConverter.ToInt32(LenK, 0);
  279.                 int lenIV = BitConverter.ToInt32(LenIV, 0);
  280.  
  281.                 // Determine the start postition of the
  282.                 // ciphter text (startC) and its length(lenC).
  283.                 int startC = lenK + lenIV + 8;
  284.                 int lenC = (int)inFs.Length - startC;
  285.  
  286.                 // Create the byte arrays for the
  287.                 // encrypted Rijndael key, the IV, and the cipher text.
  288.                 byte[] KeyEncrypted = new byte[lenK];
  289.                 byte[] IV = new byte[lenIV];
  290.  
  291.                 // Extract the key and IV starting from index 8,
  292.                 // after the length values.
  293.                 inFs.Seek(8, SeekOrigin.Begin);
  294.                 inFs.Read(KeyEncrypted, 0, lenK);
  295.                 inFs.Seek(8 + lenK, SeekOrigin.Begin);
  296.                 inFs.Read(IV, 0, lenIV);
  297.                
  298.                 // Use RSACryptoServiceProvider to decrypt the Rijndael key.
  299.                 byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);
  300.  
  301.                 // Decrypt the key.
  302.                 ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV);
  303.  
  304.                 // Decrypt the cipher text from from the FileSteam of the encrypted
  305.                 // file (inFs) into the FileStream for the decrypted file (outFs).
  306.                 using (FileStream outFs = new FileStream(outFile, FileMode.Create))
  307.                 {
  308.  
  309.                     int count = 0;
  310.                     int offset = 0;
  311.  
  312.                     // blockSizeBytes can be any arbitrary size.
  313.                     int blockSizeBytes = rjndl.BlockSize / 8;
  314.                     byte[] data = new byte[blockSizeBytes];
  315.  
  316.  
  317.                     // By decrypting one chunk at time, you can
  318.                     // save memory and accommodate large files.
  319.  
  320.                     // Begin
  321.                     inFs.Seek(startC, SeekOrigin.Begin);
  322.                     using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
  323.                     {
  324.                         do  {
  325.                             count = inFs.Read(data, 0, blockSizeBytes);
  326.                             offset += count;
  327.                             outStreamDecrypted.Write(data, 0, count);
  328.  
  329.                         } while (count > 0);
  330.  
  331.                         outStreamDecrypted.FlushFinalBlock();
  332.                     }
  333.                     outFs.Flush();
  334.                 }
  335.             }
  336.             rjndl.Clear();
  337.         }
  338.        
  339.     }
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement