Advertisement
Guest User

Untitled

a guest
Sep 13th, 2017
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 12.39 KB | None | 0 0
  1. namespace ClassLibrary1;
  2.  
  3. interface
  4.  
  5. uses
  6.   System,
  7.   System.IO,
  8.   System.Security.Cryptography,
  9.   System.Runtime.InteropServices,
  10.   System.Text;
  11.  
  12.  
  13. type
  14.   ConsoleApp = public class
  15.   private
  16.     class method hashMe(input: string): string;
  17.     class method Encrypt(clearText: string; Password: string; Salt: array of byte; iteration: Integer): string;
  18.     class method Encrypt(clearData: array of byte; Key: array of byte; IV: array of byte): array of byte;
  19.     class method Encrypt(clearData: array of byte; Password: string; Salt: array of byte; iteration: integer): array of byte;
  20.     class method Decrypt(cipherText: string; Password: string; Salt: array of byte; iterations: Integer): string;
  21.     class method Decrypt(cipherData: array of byte; Password: string; Salt: array of byte; iterations: integer): array of byte;
  22.     class method Decrypt(cipherData: array of byte; Key: array of byte; IV: array of byte): array of byte;
  23.   protected
  24.   public
  25.     [UnmanagedExport('Auth')]
  26.     class method Auth(userName: String; userPassword: String): String;
  27.   end;
  28.  
  29. implementation
  30.  
  31. class method ConsoleApp.Auth(userName: String; userPassword: String): String;
  32. begin
  33.   var iterations: Integer := 25;
  34.   //Use the current date/time to create the Salt for the encryption of the userid and password
  35.   var timeString: string := DateTime.Now.ToUniversalTime().ToString();
  36.   var encodingSalt: Array of byte := Encoding.ASCII.GetBytes(hashMe(timeString));
  37.  
  38.   //Encrypt the credentials using the entered password hash (if correct the has will match what is stored in NEWA config)
  39.   //as the encryption password along with the Salt
  40.   var pwdHash: string := hashMe(userPassword).ToLower();
  41.   var pwd: string := Encrypt(userPassword, pwdHash, encodingSalt, iterations);
  42.   var id: string := Encrypt(userName, pwdHash, encodingSalt, iterations);
  43.  
  44.   var guid_: Guid := Guid.NewGuid();
  45.   //We're encrypting the date/time we used to create the salt with the guid so the decrypt of the re-passed credentials knows
  46.   //what is used as the salt
  47.   var RL: String := Encrypt(id.Length.ToString(), pwdHash, Encoding.ASCII.GetBytes(guid_.ToString()), iterations);
  48.   var rt: string := Encrypt(timeString, pwdHash, Encoding.ASCII.GetBytes(guid_.ToString()), iterations);
  49.   var RTL: String := Encrypt(rt.Length.ToString(), pwdHash, Encoding.ASCII.GetBytes(guid_.ToString()), iterations);
  50.   var R: String := rt + id + pwd + guid_;
  51.  
  52.   result := R + '{%$DEL$%}' + RL + '{%$DEL$%}' + RTL;
  53. end;
  54.  
  55.  
  56. class method ConsoleApp.hashMe(input: string): string;
  57. begin
  58.   var x: MD5CryptoServiceProvider := new MD5CryptoServiceProvider();
  59.   var bs:  array of byte := System.Text.Encoding.UTF8.GetBytes(input);
  60.   bs := x.ComputeHash(bs);
  61.   var s: StringBuilder := new StringBuilder();
  62.   for each b: byte in bs do
  63.   begin
  64.     s.Append(b.ToString('x2').ToLower());
  65.   end;
  66.   var password: string := s.ToString();
  67.   result:=password;
  68. end;
  69.  
  70. class method ConsoleApp.Encrypt(clearText: string; Password: string; Salt: array of byte; iteration: Integer): string;
  71. begin
  72.   // First we need to turn the input string into a byte array.
  73.  
  74.   var clearBytes: Array of byte := System.Text.Encoding.Unicode.GetBytes(clearText);
  75.  
  76.   // Then, we need to turn the password into Key and IV
  77.   // We are using salt to make it harder to guess our key
  78.   // using a dictionary attack -
  79.   // trying to guess a password by enumerating all possible words.
  80.  
  81.   var pdb: Rfc2898DeriveBytes := new Rfc2898DeriveBytes(Password, Salt, iteration);
  82.  
  83.   // Now get the key/IV and do the encryption using the
  84.   // function that accepts byte arrays.
  85.   // Using PasswordDeriveBytes object we are first getting
  86.   // 32 bytes for the Key
  87.   // (the default Rijndael key length is 256bit = 32bytes)
  88.   // and then 16 bytes for the IV.
  89.   // IV should always be the block size, which is by default
  90.   // 16 bytes (128 bit) for Rijndael.
  91.   // If you are using DES/TripleDES/RC2 the block size is
  92.   // 8 bytes and so should be the IV size.
  93.   // You can also read KeySize/BlockSize properties off
  94.   // the algorithm to find out the sizes.
  95.  
  96.   var encryptedData: Array of byte := Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
  97.  
  98.   // Now we need to turn the resulting byte array into a string.
  99.   // A common mistake would be to use an Encoding class for that.
  100.   //It does not work because not all byte values can be
  101.   // represented by characters.
  102.   // We are going to be using Base64 encoding that is designed
  103.   //exactly for what we are trying to do.
  104.  
  105.   result := Convert.ToBase64String(encryptedData);
  106. end;
  107.  
  108. class method ConsoleApp.Encrypt(clearData: array of byte; Password: string; Salt: array of byte; iteration: integer): array of byte;
  109. begin
  110.   // We need to turn the password into Key and IV.
  111.   // We are using salt to make it harder to guess our key
  112.   // using a dictionary attack -
  113.   // trying to guess a password by enumerating all possible words.
  114.  
  115.   var pdb: Rfc2898DeriveBytes  := new Rfc2898DeriveBytes(Password, Salt, iteration);
  116.  
  117.   // Now get the key/IV and do the encryption using the function
  118.   // that accepts byte arrays.
  119.   // Using PasswordDeriveBytes object we are first getting
  120.   // 32 bytes for the Key
  121.   // (the default Rijndael key length is 256bit = 32bytes)
  122.   // and then 16 bytes for the IV.
  123.   // IV should always be the block size, which is by default
  124.   // 16 bytes (128 bit) for Rijndael.
  125.   // If you are using DES/TripleDES/RC2 the block size is 8
  126.   // bytes and so should be the IV size.
  127.   // You can also read KeySize/BlockSize properties off the
  128.   // algorithm to find out the sizes.
  129.  
  130.   result := Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));
  131. end;
  132.  
  133. class method ConsoleApp.Encrypt(clearData: array of byte; Key: array of byte; IV: array of byte): array of byte;
  134. begin
  135.   // Create a MemoryStream to accept the encrypted bytes
  136.   var ms: MemoryStream  := new MemoryStream();
  137.   // Create a symmetric algorithm.
  138.   // We are going to use Rijndael because it is strong and
  139.   // available on all platforms.
  140.   // You can use other algorithms, to do so substitute the
  141.   // next line with something like
  142.   //      TripleDES alg = TripleDES.Create();
  143.   var alg: Rijndael := Rijndael.Create();
  144.  
  145.   // Now set the key and the IV.
  146.   // We need the IV (Initialization Vector) because
  147.   // the algorithm is operating in its default
  148.   // mode called CBC (Cipher Block Chaining).
  149.   // The IV is XORed with the first block (8 byte)
  150.   // of the data before it is encrypted, and then each
  151.   // encrypted block is XORed with the
  152.   // following block of plaintext.
  153.   // This is done to make encryption more secure.
  154.   // There is also a mode called ECB which does not need an IV,
  155.   // but it is much less secure.
  156.   alg.Key := Key;
  157.   alg.IV := IV;
  158.  
  159.   // Create a CryptoStream through which we are going to be
  160.   // pumping our data.
  161.   // CryptoStreamMode.Write means that we are going to be
  162.   // writing data to the stream and the output will be written
  163.   // in the MemoryStream we have provided.
  164.   var cs: CryptoStream := new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
  165.  
  166.   // Write the data and make it do the encryption
  167.   cs.Write(clearData, 0, clearData.Length);
  168.  
  169.   // Close the crypto stream (or do FlushFinalBlock).
  170.   // This will tell it that we have done our encryption and
  171.   // there is no more data coming in,
  172.   // and it is now a good time to apply the padding and
  173.   // finalize the encryption process.
  174.   cs.Close();
  175.  
  176.   // Now get the encrypted data from the MemoryStream.
  177.   // Some people make a mistake of using GetBuffer() here,
  178.   // which is not the right way.
  179.   var encryptedData: Array of byte := ms.ToArray();
  180.  
  181.   result := encryptedData;
  182. end;
  183.  
  184. //////////////////////////////////
  185. // Decrypt a byte array into a byte array using a key and an IV
  186. class method ConsoleApp.Decrypt(cipherData: array of byte; Key: array of byte; IV: array of byte): array of byte;
  187. begin
  188.   // Create a MemoryStream that is going to accept the
  189.   // decrypted bytes
  190.  
  191.   var ms: MemoryStream := new MemoryStream();
  192.  
  193.   // Create a symmetric algorithm.
  194.   // We are going to use Rijndael because it is strong and
  195.   // available on all platforms.
  196.   // You can use other algorithms, to do so substitute the next
  197.   // line with something like
  198.   //     TripleDES alg = TripleDES.Create();
  199.  
  200.   var alg: Rijndael := Rijndael.Create();
  201.  
  202.   // Now set the key and the IV.
  203.   // We need the IV (Initialization Vector) because the algorithm
  204.   // is operating in its default
  205.   // mode called CBC (Cipher Block Chaining). The IV is XORed with
  206.   // the first block (8 byte)
  207.   // of the data after it is decrypted, and then each decrypted
  208.   // block is XORed with the previous
  209.   // cipher block. This is done to make encryption more secure.
  210.   // There is also a mode called ECB which does not need an IV,
  211.   // but it is much less secure.
  212.  
  213.   alg.Key := Key;
  214.   alg.IV := IV;
  215.  
  216.   // Create a CryptoStream through which we are going to be
  217.   // pumping our data.
  218.   // CryptoStreamMode.Write means that we are going to be
  219.   // writing data to the stream
  220.   // and the output will be written in the MemoryStream
  221.   // we have provided.
  222.  
  223.   var cs: CryptoStream := new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
  224.  
  225.   // Write the data and make it do the decryption
  226.  
  227.   cs.Write(cipherData, 0, cipherData.Length);
  228.  
  229.   // Close the crypto stream (or do FlushFinalBlock).
  230.   // This will tell it that we have done our decryption
  231.   // and there is no more data coming in,
  232.   // and it is now a good time to remove the padding
  233.   // and finalize the decryption process.
  234.  
  235.   cs.Close();
  236.  
  237.   // Now get the decrypted data from the MemoryStream.
  238.   // Some people make a mistake of using GetBuffer() here,
  239.   // which is not the right way.
  240.  
  241.   var decryptedData: Array of byte := ms.ToArray();
  242.  
  243.   result := decryptedData;
  244. end;
  245.  
  246. // Decrypt a string into a string using a password
  247. //    Uses Decrypt(byte[], byte[], byte[])
  248. class method ConsoleApp.Decrypt(cipherText: string; Password: string; Salt: array of byte; iterations: Integer): string;
  249. begin
  250.   // First we need to turn the input string into a byte array.
  251.   // We presume that Base64 encoding was used
  252.  
  253.   var cipherBytes: Array of byte := Convert.FromBase64String(cipherText);
  254.  
  255.   // Then, we need to turn the password into Key and IV
  256.   // We are using salt to make it harder to guess our key
  257.   // using a dictionary attack -
  258.   // trying to guess a password by enumerating all possible words.
  259.  
  260.   var pdb: Rfc2898DeriveBytes  := new Rfc2898DeriveBytes(Password, Salt, iterations);
  261.  
  262.   // Now get the key/IV and do the decryption using
  263.   // the function that accepts byte arrays.
  264.   // Using PasswordDeriveBytes object we are first
  265.   // getting 32 bytes for the Key
  266.   // (the default Rijndael key length is 256bit = 32bytes)
  267.   // and then 16 bytes for the IV.
  268.   // IV should always be the block size, which is by
  269.   // default 16 bytes (128 bit) for Rijndael.
  270.   // If you are using DES/TripleDES/RC2 the block size is
  271.   // 8 bytes and so should be the IV size.
  272.   // You can also read KeySize/BlockSize properties off
  273.   // the algorithm to find out the sizes.
  274.  
  275.   var decryptedData: Array of byte := Decrypt(cipherBytes, pdb.GetBytes(32), pdb.GetBytes(16));
  276.  
  277.   // Now we need to turn the resulting byte array into a string.
  278.   // A common mistake would be to use an Encoding class for that.
  279.   // It does not work
  280.   // because not all byte values can be represented by characters.
  281.   // We are going to be using Base64 encoding that is
  282.   // designed exactly for what we are trying to do.
  283.  
  284.   result := System.Text.Encoding.Unicode.GetString(decryptedData);
  285. end;
  286.  
  287. // Decrypt bytes into bytes using a password
  288. //    Uses Decrypt(byte[], byte[], byte[])
  289.  
  290.  
  291. class method ConsoleApp.Decrypt(cipherData: array of byte; Password: string; Salt: array of byte; iterations: integer): array of byte;
  292. begin
  293.   // We need to turn the password into Key and IV.
  294.   // We are using salt to make it harder to guess our key
  295.   // using a dictionary attack -
  296.   // trying to guess a password by enumerating all possible words.
  297.  
  298.   var pdb: Rfc2898DeriveBytes := new Rfc2898DeriveBytes(Password, Salt, iterations);
  299.  
  300.   // Now get the key/IV and do the Decryption using the
  301.   //function that accepts byte arrays.
  302.   // Using PasswordDeriveBytes object we are first getting
  303.   // 32 bytes for the Key
  304.   // (the default Rijndael key length is 256bit = 32bytes)
  305.   // and then 16 bytes for the IV.
  306.   // IV should always be the block size, which is by default
  307.   // 16 bytes (128 bit) for Rijndael.
  308.   // If you are using DES/TripleDES/RC2 the block size is
  309.   // 8 bytes and so should be the IV size.
  310.   // You can also read KeySize/BlockSize properties off the
  311.   // algorithm to find out the sizes.
  312.  
  313.   result := Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16));
  314. end;
  315.  
  316. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement