The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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. return Hash(valueBytes);
  90. }
  91. public static string Hash(byte[] value)
  92. {
  93. HashAlgorithm hash = new SHA256CryptoServiceProvider();
  94. byte[] hashBytes = hash.ComputeHash(value);
  95. return Convert.ToBase64String(hashBytes);
  96. }
  97. public static byte[] Hash(Stream value)
  98. {
  99. HashAlgorithm hash = new SHA256CryptoServiceProvider();
  100. return hash.ComputeHash(value);
  101. }
  102. public static string Hash(string value, string salt1, string salt2)
  103. {
  104. SHA256Managed hash = new SHA256Managed();
  105. SHA1 sha1 = new SHA1Managed();
  106. // gen salt2 hash
  107. byte[] dataSalt2 = Encoding.UTF8.GetBytes(salt2);
  108. byte[] salt2Bytes = hash.ComputeHash(dataSalt2);
  109. string salt2Str = string.Empty;
  110. foreach (byte x in salt2Bytes)
  111. {
  112. salt2Str += String.Format("{0:x2}", x);
  113. }
  114. string dataStr = salt1 + value + salt2Str;
  115. byte[] dataStrBytes = Encoding.UTF8.GetBytes(dataStr);
  116. byte[] shaBytes = sha1.ComputeHash(dataStrBytes);
  117. string sha1Str = string.Empty;
  118. foreach (byte x in shaBytes)
  119. {
  120. sha1Str += String.Format("{0:x2}", x);
  121. }
  122. byte[] sha1Bytes = Encoding.UTF8.GetBytes(sha1Str);
  123. byte[] valueBytes = hash.ComputeHash(sha1Bytes);
  124. string hashString = string.Empty;
  125. foreach (byte x in valueBytes)
  126. {
  127. hashString += String.Format("{0:x2}", x);
  128. }
  129. return hashString;
  130. }
  131. public static System.Security.Cryptography.SHA256 CreateHashAlgorithm()
  132. {
  133. if (CryptoConfig.AllowOnlyFipsAlgorithms)
  134. {
  135. return new SHA256CryptoServiceProvider();
  136. }
  137. return new SHA256Managed();
  138. }
  139. }
  140. public class AES
  141. {
  142. public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
  143. {
  144. return Decrypt(data, key, iv, "CTR", "NoPadding");
  145. }
  146. public static byte[] Decrypt(byte[] data, string key, string iv)
  147. {
  148. byte[] keyBytes = Encoding.UTF8.GetBytes(key);
  149. byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
  150. return Decrypt(data, keyBytes, ivBytes, "CTR", "NoPadding");
  151. }
  152. public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv, string mode, string padding)
  153. {
  154. using (MemoryStream stream = new MemoryStream(data))
  155. {
  156. return ProcessCipher(false, stream, 1024, key, iv, mode, padding);
  157. }
  158. }
  159. public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
  160. {
  161. return Encrypt(data, key, iv, "CTR", "NoPadding");
  162. }
  163. public static byte[] Encrypt(byte[] data, string key, string iv)
  164. {
  165. byte[] keyBytes = Encoding.UTF8.GetBytes(key);
  166. byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
  167. return Encrypt(data, keyBytes, ivBytes, "CTR", "NoPadding");
  168. }
  169. public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv, string mode, string padding)
  170. {
  171. using (MemoryStream stream = new MemoryStream(data))
  172. {
  173. return ProcessCipher(true, stream, 1024, key, iv, mode, padding);
  174. }
  175. }
  176. public static byte[] ProcessCipher(bool encrypt, Stream input, int chunkSize, byte[] key, byte[] iv, string mode, string padding)
  177. {
  178. // Create the cipher we are going to use
  179. IBufferedCipher cipher = CreateCipher(encrypt, key, iv, mode, padding);
  180. // Make sure the input stream is at the beginning
  181. input.Seek(0, SeekOrigin.Begin);
  182. // Initialize variables
  183. byte[] output = new byte[input.Length];
  184. int cipherOffset = 0;
  185. int processedBytes = 0;
  186. // Process the stream and save the bytes to the output
  187. do
  188. {
  189. processedBytes = ProcessCipherBlock(cipher, input, chunkSize, output, cipherOffset);
  190. cipherOffset += processedBytes;
  191. }
  192. while (processedBytes > 0);
  193. // Finalize processing of the cipher
  194. FinalizeCipherBlock(cipher, output, cipherOffset);
  195. return output;
  196. }
  197. public static void EncryptToFile(string filePath, Stream input, int chunkSize, byte[] key, byte[] iv, string mode, string padding)
  198. {
  199. IBufferedCipher cipher = CreateCipher(true, key, iv, mode, padding);
  200. // Make sure the input stream is at the beginning
  201. input.Seek(0, SeekOrigin.Begin);
  202. using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
  203. {
  204. int processedBytes = 0;
  205. byte[] buffer = new byte[chunkSize];
  206. do
  207. {
  208. processedBytes = ProcessCipherBlock(cipher, input, chunkSize, buffer, 0);
  209. if (processedBytes > 0)
  210. {
  211. // We have bytes, lets write them to the file
  212. fileStream.Write(buffer, 0, processedBytes);
  213. // Clear the buffer
  214. Array.Clear(buffer, 0, chunkSize);
  215. }
  216. }
  217. while (processedBytes > 0);
  218. // Clear the buffer
  219. Array.Clear(buffer, 0, chunkSize);
  220. // Finalize processing of the cipher
  221. processedBytes = FinalizeCipherBlock(cipher, buffer, 0);
  222. if (processedBytes > 0)
  223. {
  224. // We have bytes, lets write them to the file
  225. fileStream.Write(buffer, 0, processedBytes);
  226. }
  227. }
  228. }
  229. public static IBufferedCipher CreateCipher(bool encrypt, byte[] key, byte[] iv, string mode, string padding)
  230. {
  231. IBufferedCipher cipher = CipherUtilities.GetCipher("AES/" + mode + "/" + padding);
  232. cipher.Init(encrypt, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", key), iv));
  233. return cipher;
  234. }
  235. public static int ProcessCipherBlock(IBufferedCipher cipher, Stream input, int chunkSize, byte[] output, int outputOffset)
  236. {
  237. // Initialize buffer
  238. byte[] buffer = new byte[chunkSize];
  239. // Read the next block of data
  240. int bytesRead = input.Read(buffer, 0, chunkSize);
  241. if (bytesRead > 0)
  242. {
  243. // process the cipher for the read block and add it to the output
  244. return cipher.ProcessBytes(buffer, 0, bytesRead, output, outputOffset);
  245. }
  246. return 0;
  247. }
  248. public static int FinalizeCipherBlock(IBufferedCipher cipher, byte[] output, int outputOffset)
  249. {
  250. // perform final action on cipher
  251. return cipher.DoFinal(output, outputOffset);
  252. }
  253. public static byte[] CreateKey(string password, string iv, int keySize = 256)
  254. {
  255. byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
  256. return CreateKey(password, ivBytes, keySize);
  257. }
  258. public static byte[] CreateKey(string password, byte[] iv, int keySize = 256)
  259. {
  260. const int Iterations = 300;
  261. var keyGenerator = new Rfc2898DeriveBytes(password, iv, Iterations);
  262. return keyGenerator.GetBytes(keySize / 8);
  263. }
  264. }
  265. public static class PGP
  266. {
  267. public static bool IsPublicKey(string key)
  268. {
  269. bool isValid = false;
  270. try
  271. {
  272. byte[] byteArray = Encoding.ASCII.GetBytes(key);
  273. using (MemoryStream stream = new MemoryStream(byteArray))
  274. {
  275. using (Stream decoderStream = PgpUtilities.GetDecoderStream(stream))
  276. {
  277. PgpPublicKeyRingBundle publicKeyBundle = new PgpPublicKeyRingBundle(decoderStream);
  278. PgpPublicKey foundKey = GetFirstPublicKey(publicKeyBundle);
  279. if (foundKey != null)
  280. {
  281. isValid = true;
  282. }
  283. }
  284. }
  285. }
  286. catch (Exception ex)
  287. {
  288. isValid = false;
  289. }
  290. return isValid;
  291. }
  292. public static string GetFingerprint(string key)
  293. {
  294. string hexString = string.Empty;
  295. byte[] byteArray = Encoding.ASCII.GetBytes(key);
  296. using (MemoryStream stream = new MemoryStream(byteArray))
  297. {
  298. using (Stream decoderStream = PgpUtilities.GetDecoderStream(stream))
  299. {
  300. PgpPublicKeyRingBundle publicKeyBundle = new PgpPublicKeyRingBundle(decoderStream);
  301. PgpPublicKey foundKey = GetFirstPublicKey(publicKeyBundle);
  302. if (foundKey != null)
  303. {
  304. byte[] fing = foundKey.GetFingerprint();
  305. hexString = Hex.ToHexString(fing);
  306. }
  307. }
  308. }
  309. return hexString;
  310. }
  311. public static string GetFingerprint64(string key)
  312. {
  313. string fingerprint = GetFingerprint(key);
  314. if (fingerprint.Length > 16)
  315. fingerprint = fingerprint.Substring(fingerprint.Length - 16);
  316. return fingerprint;
  317. }
  318. private static PgpPublicKey GetFirstPublicKey(PgpPublicKeyRingBundle publicKeyRingBundle)
  319. {
  320. foreach (PgpPublicKeyRing kRing in publicKeyRingBundle.GetKeyRings())
  321. {
  322. var keys = kRing.GetPublicKeys();
  323. foreach (var key in keys)
  324. {
  325. PgpPublicKey foundKey = (PgpPublicKey)key;
  326. //PgpPublicKey key = kRing.GetPublicKeys()
  327. //.Cast<PgpPublicKey>()
  328. // .Where(k => k.IsEncryptionKey)
  329. // .FirstOrDefault();
  330. if (foundKey != null && foundKey.IsEncryptionKey)
  331. return foundKey;
  332. }
  333. }
  334. return null;
  335. }
  336. }
  337. }