Guest User

Untitled

a guest
Jun 25th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.69 KB | None | 0 0
  1. using System;
  2. using System.Security.Cryptography;
  3. using System.Text;
  4.  
  5. class AesDemo {
  6.  
  7. const int HASH_SIZE = 32; //SHA256
  8.  
  9. /// <summary>Performs encryption with random IV (prepended to output), and includes hash of plaintext for verification.</summary>
  10. public static byte[] Encrypt(string password, byte[] passwordSalt, byte[] plainText) {
  11. // Construct message with hash
  12. var msg = new byte[HASH_SIZE + plainText.Length];
  13. var hash = computeHash(plainText, 0, plainText.Length);
  14. Buffer.BlockCopy(hash, 0, msg, 0, HASH_SIZE);
  15. Buffer.BlockCopy(plainText, 0, msg, HASH_SIZE, plainText.Length);
  16.  
  17. // Encrypt
  18. using (var aes = createAes(password, passwordSalt)) {
  19. aes.GenerateIV();
  20. using (var enc = aes.CreateEncryptor()) {
  21.  
  22. var encBytes = enc.TransformFinalBlock(msg, 0, msg.Length);
  23. // Prepend IV to result
  24. var res = new byte[aes.IV.Length + encBytes.Length];
  25. Buffer.BlockCopy(aes.IV, 0, res, 0, aes.IV.Length);
  26. Buffer.BlockCopy(encBytes, 0, res, aes.IV.Length, encBytes.Length);
  27. return res;
  28. }
  29. }
  30. }
  31.  
  32. public static byte[] Decrypt(string password, byte[] passwordSalt, byte[] cipherText) {
  33. using (var aes = createAes(password, passwordSalt)) {
  34. var iv = new byte[aes.IV.Length];
  35. Buffer.BlockCopy(cipherText, 0, iv, 0, iv.Length);
  36. aes.IV = iv; // Probably could copy right to the byte array, but that's not guaranteed
  37.  
  38. using (var dec = aes.CreateDecryptor()) {
  39. var decBytes = dec.TransformFinalBlock(cipherText, iv.Length, cipherText.Length - iv.Length);
  40.  
  41. // Verify hash
  42. var hash = computeHash(decBytes, HASH_SIZE, decBytes.Length - HASH_SIZE);
  43. var existingHash = new byte[HASH_SIZE];
  44. Buffer.BlockCopy(decBytes, 0, existingHash, 0, HASH_SIZE);
  45. if (!compareBytes(existingHash, hash)){
  46. throw new CryptographicException("Message hash incorrect.");
  47. }
  48.  
  49. // Hash is valid, we're done
  50. var res = new byte[decBytes.Length - HASH_SIZE];
  51. Buffer.BlockCopy(decBytes, HASH_SIZE, res, 0, res.Length);
  52. return res;
  53. }
  54. }
  55. }
  56.  
  57. static bool compareBytes(byte[] a1, byte[] a2) {
  58. if (a1.Length != a2.Length) return false;
  59. for (int i = 0; i < a1.Length; i++) {
  60. if (a1[i] != a2[i]) return false;
  61. }
  62. return true;
  63. }
  64.  
  65. static Aes createAes(string password, byte[] salt) {
  66. // Salt may not be needed if password is safe
  67. if (password.Length < 8) throw new ArgumentException("Password must be at least 8 characters.", "password");
  68. if (salt.Length < 8) throw new ArgumentException("Salt must be at least 8 bytes.", "salt");
  69. var pdb = new PasswordDeriveBytes(password, salt, "SHA512", 129);
  70. var key = pdb.GetBytes(16);
  71.  
  72. var aes = Aes.Create();
  73. aes.Mode = CipherMode.CBC;
  74. aes.Key = pdb.GetBytes(aes.KeySize / 8);
  75. return aes;
  76. }
  77.  
  78. static byte[] computeHash(byte[] data, int offset, int count) {
  79. using (var sha = SHA256.Create()) {
  80. return sha.ComputeHash(data, offset, count);
  81. }
  82. }
  83.  
  84. public static void Main() {
  85. var password = "1234567890!";
  86. var salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
  87. var ct1 = Encrypt(password, salt, Encoding.UTF8.GetBytes("Alice; Bob; Eve;: PerformAct1"));
  88. Console.WriteLine(Convert.ToBase64String(ct1));
  89. var ct2 = Encrypt(password, salt, Encoding.UTF8.GetBytes("Alice; Bob; Eve;: PerformAct2"));
  90. Console.WriteLine(Convert.ToBase64String(ct2));
  91.  
  92. var pt1 = Decrypt(password, salt, ct1);
  93. Console.WriteLine(Encoding.UTF8.GetString(pt1));
  94. var pt2 = Decrypt(password, salt, ct2);
  95. Console.WriteLine(Encoding.UTF8.GetString(pt2));
  96.  
  97. // Now check tampering
  98. try {
  99. ct1[30]++;
  100. Decrypt(password, salt, ct1);
  101. Console.WriteLine("Error: tamper detection failed.");
  102. } catch (Exception ex) {
  103. Console.WriteLine("Success: tampering detected.");
  104. Console.WriteLine(ex.ToString());
  105. }
  106. }
  107. }
  108.  
  109. public static void Main() {
  110. var buff = new byte[8];
  111. new Random().NextBytes(buff);
  112. var v = BitConverter.ToUInt64(buff, 0);
  113. Console.WriteLine("Value: " + v.ToString());
  114. Console.WriteLine("Value (bytes): " + BitConverter.ToString(BitConverter.GetBytes(v)));
  115. var aes = Aes.Create();
  116. aes.GenerateIV();
  117. aes.GenerateKey();
  118. var encBytes = aes.CreateEncryptor().TransformFinalBlock(BitConverter.GetBytes(v), 0, 8);
  119. Console.WriteLine("Encrypted: " + BitConverter.ToString(encBytes));
  120. var dec = aes.CreateDecryptor();
  121. Console.WriteLine("Decrypted: " + BitConverter.ToUInt64(dec.TransformFinalBlock(encBytes, 0, encBytes.Length), 0));
  122. for (int i = 0; i < 8; i++) {
  123. for (int x = 0; x < 250; x++) {
  124. encBytes[i]++;
  125. try {
  126. Console.WriteLine("Attacked: " + BitConverter.ToUInt64(dec.TransformFinalBlock(encBytes, 0, encBytes.Length), 0));
  127. return;
  128. } catch { }
  129. }
  130. }
  131. }
  132.  
  133. using System;
  134. using System.Data;
  135. using System.Security.Cryptography;
  136. using System.IO;
  137.  
  138.  
  139. public class SimpleAES
  140. {
  141. // Change these keys
  142. private byte[] Key = { 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 };
  143. private byte[] Vector = { 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 };
  144.  
  145.  
  146. private ICryptoTransform EncryptorTransform, DecryptorTransform;
  147. private System.Text.UTF8Encoding UTFEncoder;
  148.  
  149. public SimpleAES()
  150. {
  151. //This is our encryption method
  152. RijndaelManaged rm = new RijndaelManaged();
  153.  
  154. //Create an encryptor and a decryptor using our encryption method, key, and vector.
  155. EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);
  156. DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);
  157.  
  158. //Used to translate bytes to text and vice versa
  159. UTFEncoder = new System.Text.UTF8Encoding();
  160. }
  161.  
  162. /// -------------- Two Utility Methods (not used but may be useful) -----------
  163. /// Generates an encryption key.
  164. static public byte[] GenerateEncryptionKey()
  165. {
  166. //Generate a Key.
  167. RijndaelManaged rm = new RijndaelManaged();
  168. rm.GenerateKey();
  169. return rm.Key;
  170. }
  171.  
  172. /// Generates a unique encryption vector
  173. static public byte[] GenerateEncryptionVector()
  174. {
  175. //Generate a Vector
  176. RijndaelManaged rm = new RijndaelManaged();
  177. rm.GenerateIV();
  178. return rm.IV;
  179. }
  180.  
  181.  
  182. /// ----------- The commonly used methods ------------------------------
  183. /// Encrypt some text and return a string suitable for passing in a URL.
  184. public string EncryptToString(string TextValue)
  185. {
  186. return ByteArrToString(Encrypt(TextValue));
  187. }
  188.  
  189. /// Encrypt some text and return an encrypted byte array.
  190. public byte[] Encrypt(string TextValue)
  191. {
  192. //Translates our text value into a byte array.
  193. Byte[] bytes = UTFEncoder.GetBytes(TextValue);
  194.  
  195. //Used to stream the data in and out of the CryptoStream.
  196. MemoryStream memoryStream = new MemoryStream();
  197.  
  198. /*
  199. * We will have to write the unencrypted bytes to the stream,
  200. * then read the encrypted result back from the stream.
  201. */
  202. #region Write the decrypted value to the encryption stream
  203. CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);
  204. cs.Write(bytes, 0, bytes.Length);
  205. cs.FlushFinalBlock();
  206. #endregion
  207.  
  208. #region Read encrypted value back out of the stream
  209. memoryStream.Position = 0;
  210. byte[] encrypted = new byte[memoryStream.Length];
  211. memoryStream.Read(encrypted, 0, encrypted.Length);
  212. #endregion
  213.  
  214. //Clean up.
  215. cs.Close();
  216. memoryStream.Close();
  217.  
  218. return encrypted;
  219. }
  220.  
  221. /// The other side: Decryption methods
  222. public string DecryptString(string EncryptedString)
  223. {
  224. return Decrypt(StrToByteArray(EncryptedString));
  225. }
  226.  
  227. /// Decryption when working with byte arrays.
  228. public string Decrypt(byte[] EncryptedValue)
  229. {
  230. #region Write the encrypted value to the decryption stream
  231. MemoryStream encryptedStream = new MemoryStream();
  232. CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);
  233. decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
  234. decryptStream.FlushFinalBlock();
  235. #endregion
  236.  
  237. #region Read the decrypted value from the stream.
  238. encryptedStream.Position = 0;
  239. Byte[] decryptedBytes = new Byte[encryptedStream.Length];
  240. encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);
  241. encryptedStream.Close();
  242. #endregion
  243. return UTFEncoder.GetString(decryptedBytes);
  244. }
  245.  
  246. /// Convert a string to a byte array. NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).
  247. // System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
  248. // return encoding.GetBytes(str);
  249. // However, this results in character values that cannot be passed in a URL. So, instead, I just
  250. // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).
  251. public byte[] StrToByteArray(string str)
  252. {
  253. if (str.Length == 0)
  254. throw new Exception("Invalid string value in StrToByteArray");
  255.  
  256. byte val;
  257. byte[] byteArr = new byte[str.Length / 3];
  258. int i = 0;
  259. int j = 0;
  260. do
  261. {
  262. val = byte.Parse(str.Substring(i, 3));
  263. byteArr[j++] = val;
  264. i += 3;
  265. }
  266. while (i < str.Length);
  267. return byteArr;
  268. }
  269.  
  270. // Same comment as above. Normally the conversion would use an ASCII encoding in the other direction:
  271. // System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
  272. // return enc.GetString(byteArr);
  273. public string ByteArrToString(byte[] byteArr)
  274. {
  275. byte val;
  276. string tempStr = "";
  277. for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
  278. {
  279. val = byteArr[i];
  280. if (val < (byte)10)
  281. tempStr += "00" + val.ToString();
  282. else if (val < (byte)100)
  283. tempStr += "0" + val.ToString();
  284. else
  285. tempStr += val.ToString();
  286. }
  287. return tempStr;
  288. }
  289. }
Add Comment
Please, Sign In to add comment