The next generation of the Teknik Services. Written in ASP.NET.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Crypto.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. using System.Text;
  2. using SecurityDriven.Inferno.Hash;
  3. using SecurityDriven.Inferno.Mac;
  4. using System.IO;
  5. using System.Security.Cryptography;
  6. using Org.BouncyCastle.Crypto;
  7. using Org.BouncyCastle.Crypto.Engines;
  8. using Org.BouncyCastle.Crypto.Modes;
  9. using Org.BouncyCastle.Crypto.Paddings;
  10. using Org.BouncyCastle.Crypto.Parameters;
  11. using Org.BouncyCastle.Security;
  12. using Org.BouncyCastle.Utilities.Encoders;
  13. using Org.BouncyCastle.Bcpg.OpenPgp;
  14. using Org.BouncyCastle.Utilities.IO;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.IO.MemoryMappedFiles;
  18. namespace Teknik.Utilities
  19. {
  20. public class MD5
  21. {
  22. public static string Hash(string value)
  23. {
  24. byte[] valBytes = Encoding.ASCII.GetBytes(value);
  25. System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
  26. byte[] hashBytes = md5.ComputeHash(valBytes);
  27. StringBuilder sBuilder = new StringBuilder();
  28. // Loop through each byte of the hashed data
  29. // and format each one as a hexadecimal string.
  30. for (int i = 0; i < hashBytes.Length; i++)
  31. {
  32. sBuilder.Append(hashBytes[i].ToString("x2"));
  33. }
  34. // Return the hexadecimal string.
  35. return sBuilder.ToString();
  36. }
  37. public static string FileHash(string filename)
  38. {
  39. try
  40. {
  41. using (var md5 = System.Security.Cryptography.MD5.Create())
  42. {
  43. using (var stream = File.OpenRead(filename))
  44. {
  45. return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
  46. }
  47. }
  48. }
  49. catch (Exception)
  50. {
  51. return string.Empty;
  52. }
  53. }
  54. public static string DataHash(string data)
  55. {
  56. try
  57. {
  58. using (var md5 = System.Security.Cryptography.MD5.Create())
  59. {
  60. // convert string to stream
  61. byte[] byteArray = Encoding.UTF8.GetBytes(data);
  62. using (MemoryStream stream = new MemoryStream(byteArray))
  63. {
  64. return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
  65. }
  66. }
  67. }
  68. catch (Exception)
  69. {
  70. return string.Empty;
  71. }
  72. }
  73. }
  74. public class SHA384
  75. {
  76. public static byte[] Hash(string key, string value)
  77. {
  78. byte[] keyBytes = Encoding.UTF8.GetBytes(key);
  79. byte[] data = Encoding.UTF8.GetBytes(value);
  80. byte[] result = new HMAC2(HashFactories.SHA384, keyBytes).ComputeHash(data);
  81. return result;
  82. }
  83. }
  84. public class SHA256
  85. {
  86. public static string Hash(string value)
  87. {
  88. byte[] valueBytes = Encoding.Unicode.GetBytes(value);
  89. HashAlgorithm hash = new SHA256CryptoServiceProvider();
  90. byte[] hashBytes = hash.ComputeHash(valueBytes);
  91. return Convert.ToBase64String(hashBytes);
  92. }
  93. public static string Hash(string value, string salt1, string salt2)
  94. {
  95. SHA256Managed hash = new SHA256Managed();
  96. SHA1 sha1 = new SHA1Managed();
  97. // gen salt2 hash
  98. byte[] dataSalt2 = Encoding.UTF8.GetBytes(salt2);
  99. byte[] salt2Bytes = hash.ComputeHash(dataSalt2);
  100. string salt2Str = string.Empty;
  101. foreach (byte x in salt2Bytes)
  102. {
  103. salt2Str += String.Format("{0:x2}", x);
  104. }
  105. string dataStr = salt1 + value + salt2Str;
  106. byte[] dataStrBytes = Encoding.UTF8.GetBytes(dataStr);
  107. byte[] shaBytes = sha1.ComputeHash(dataStrBytes);
  108. string sha1Str = string.Empty;
  109. foreach (byte x in shaBytes)
  110. {
  111. sha1Str += String.Format("{0:x2}", x);
  112. }
  113. byte[] sha1Bytes = Encoding.UTF8.GetBytes(sha1Str);
  114. byte[] valueBytes = hash.ComputeHash(sha1Bytes);
  115. string hashString = string.Empty;
  116. foreach (byte x in valueBytes)
  117. {
  118. hashString += String.Format("{0:x2}", x);
  119. }
  120. return hashString;
  121. }
  122. public static System.Security.Cryptography.SHA256 CreateHashAlgorithm()
  123. {
  124. if (CryptoConfig.AllowOnlyFipsAlgorithms)
  125. {
  126. return new SHA256CryptoServiceProvider();
  127. }
  128. return new SHA256Managed();
  129. }
  130. }
  131. public class AES
  132. {
  133. public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
  134. {
  135. return Decrypt(data, key, iv, "CTR", "NoPadding");
  136. }
  137. public static byte[] Decrypt(byte[] data, string key, string iv)
  138. {
  139. byte[] keyBytes = Encoding.UTF8.GetBytes(key);
  140. byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
  141. return Decrypt(data, keyBytes, ivBytes, "CTR", "NoPadding");
  142. }
  143. public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv, string mode, string padding)
  144. {
  145. using (MemoryStream stream = new MemoryStream(data))
  146. {
  147. return ProcessCipher(false, stream, 1024, key, iv, mode, padding);
  148. }
  149. }
  150. public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
  151. {
  152. return Encrypt(data, key, iv, "CTR", "NoPadding");
  153. }
  154. public static byte[] Encrypt(byte[] data, string key, string iv)
  155. {
  156. byte[] keyBytes = Encoding.UTF8.GetBytes(key);
  157. byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
  158. return Encrypt(data, keyBytes, ivBytes, "CTR", "NoPadding");
  159. }
  160. public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv, string mode, string padding)
  161. {
  162. using (MemoryStream stream = new MemoryStream(data))
  163. {
  164. return ProcessCipher(true, stream, 1024, key, iv, mode, padding);
  165. }
  166. }
  167. public static byte[] ProcessCipher(bool encrypt, Stream input, int chunkSize, byte[] key, byte[] iv, string mode, string padding)
  168. {
  169. // Create the cipher we are going to use
  170. IBufferedCipher cipher = CreateCipher(encrypt, key, iv, mode, padding);
  171. // Make sure the input stream is at the beginning
  172. input.Seek(0, SeekOrigin.Begin);
  173. // Initialize variables
  174. byte[] output = new byte[input.Length];
  175. int cipherOffset = 0;
  176. int processedBytes = 0;
  177. // Process the stream and save the bytes to the output
  178. do
  179. {
  180. processedBytes = ProcessCipherBlock(cipher, input, chunkSize, output, cipherOffset);
  181. cipherOffset += processedBytes;
  182. }
  183. while (processedBytes > 0);
  184. // Finalize processing of the cipher
  185. FinalizeCipherBlock(cipher, output, cipherOffset);
  186. return output;
  187. }
  188. public static void EncryptToFile(string filePath, Stream input, int chunkSize, byte[] key, byte[] iv, string mode, string padding)
  189. {
  190. IBufferedCipher cipher = CreateCipher(true, key, iv, mode, padding);
  191. // Make sure the input stream is at the beginning
  192. input.Seek(0, SeekOrigin.Begin);
  193. using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
  194. {
  195. int processedBytes = 0;
  196. byte[] buffer = new byte[chunkSize];
  197. do
  198. {
  199. processedBytes = ProcessCipherBlock(cipher, input, chunkSize, buffer, 0);
  200. if (processedBytes > 0)
  201. {
  202. // We have bytes, lets write them to the file
  203. fileStream.Write(buffer, 0, processedBytes);
  204. // Clear the buffer
  205. Array.Clear(buffer, 0, chunkSize);
  206. }
  207. }
  208. while (processedBytes > 0);
  209. // Clear the buffer
  210. Array.Clear(buffer, 0, chunkSize);
  211. // Finalize processing of the cipher
  212. processedBytes = FinalizeCipherBlock(cipher, buffer, 0);
  213. if (processedBytes > 0)
  214. {
  215. // We have bytes, lets write them to the file
  216. fileStream.Write(buffer, 0, processedBytes);
  217. }
  218. }
  219. }
  220. public static IBufferedCipher CreateCipher(bool encrypt, byte[] key, byte[] iv, string mode, string padding)
  221. {
  222. IBufferedCipher cipher = CipherUtilities.GetCipher("AES/" + mode + "/" + padding);
  223. cipher.Init(encrypt, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", key), iv));
  224. return cipher;
  225. }
  226. public static int ProcessCipherBlock(IBufferedCipher cipher, Stream input, int chunkSize, byte[] output, int outputOffset)
  227. {
  228. // Initialize buffer
  229. byte[] buffer = new byte[chunkSize];
  230. // Read the next block of data
  231. int bytesRead = input.Read(buffer, 0, chunkSize);
  232. if (bytesRead > 0)
  233. {
  234. // process the cipher for the read block and add it to the output
  235. return cipher.ProcessBytes(buffer, 0, bytesRead, output, outputOffset);
  236. }
  237. return 0;
  238. }
  239. public static int FinalizeCipherBlock(IBufferedCipher cipher, byte[] output, int outputOffset)
  240. {
  241. // perform final action on cipher
  242. return cipher.DoFinal(output, outputOffset);
  243. }
  244. public static byte[] CreateKey(string password, string iv, int keySize = 256)
  245. {
  246. byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
  247. return CreateKey(password, ivBytes, keySize);
  248. }
  249. public static byte[] CreateKey(string password, byte[] iv, int keySize = 256)
  250. {
  251. const int Iterations = 300;
  252. var keyGenerator = new Rfc2898DeriveBytes(password, iv, Iterations);
  253. return keyGenerator.GetBytes(keySize / 8);
  254. }
  255. }
  256. public static class PGP
  257. {
  258. public static bool IsPublicKey(string key)
  259. {
  260. bool isValid = false;
  261. try
  262. {
  263. byte[] byteArray = Encoding.ASCII.GetBytes(key);
  264. using (MemoryStream stream = new MemoryStream(byteArray))
  265. {
  266. using (Stream decoderStream = PgpUtilities.GetDecoderStream(stream))
  267. {
  268. PgpPublicKeyRingBundle publicKeyBundle = new PgpPublicKeyRingBundle(decoderStream);
  269. PgpPublicKey foundKey = GetFirstPublicKey(publicKeyBundle);
  270. if (foundKey != null)
  271. {
  272. isValid = true;
  273. }
  274. }
  275. }
  276. }
  277. catch (Exception ex)
  278. {
  279. isValid = false;
  280. }
  281. return isValid;
  282. }
  283. public static string GetFingerprint(string key)
  284. {
  285. string hexString = string.Empty;
  286. byte[] byteArray = Encoding.ASCII.GetBytes(key);
  287. using (MemoryStream stream = new MemoryStream(byteArray))
  288. {
  289. using (Stream decoderStream = PgpUtilities.GetDecoderStream(stream))
  290. {
  291. PgpPublicKeyRingBundle publicKeyBundle = new PgpPublicKeyRingBundle(decoderStream);
  292. PgpPublicKey foundKey = GetFirstPublicKey(publicKeyBundle);
  293. if (foundKey != null)
  294. {
  295. byte[] fing = foundKey.GetFingerprint();
  296. hexString = Hex.ToHexString(fing);
  297. }
  298. }
  299. }
  300. return hexString;
  301. }
  302. public static string GetFingerprint64(string key)
  303. {
  304. string fingerprint = GetFingerprint(key);
  305. if (fingerprint.Length > 16)
  306. fingerprint = fingerprint.Substring(fingerprint.Length - 16);
  307. return fingerprint;
  308. }
  309. private static PgpPublicKey GetFirstPublicKey(PgpPublicKeyRingBundle publicKeyRingBundle)
  310. {
  311. foreach (PgpPublicKeyRing kRing in publicKeyRingBundle.GetKeyRings())
  312. {
  313. var keys = kRing.GetPublicKeys();
  314. foreach (var key in keys)
  315. {
  316. PgpPublicKey foundKey = (PgpPublicKey)key;
  317. //PgpPublicKey key = kRing.GetPublicKeys()
  318. //.Cast<PgpPublicKey>()
  319. // .Where(k => k.IsEncryptionKey)
  320. // .FirstOrDefault();
  321. if (foundKey != null && foundKey.IsEncryptionKey)
  322. return foundKey;
  323. }
  324. }
  325. return null;
  326. }
  327. }
  328. }