SecurityUtil.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Security.Cryptography;
  6. namespace Top.Api.Util
  7. {
  8. /// <summary>
  9. /// 安全工具类
  10. /// </summary>
  11. public abstract class SecurityUtil
  12. {
  13. private static readonly char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".ToCharArray();
  14. private static readonly int[] IA = InitIA();
  15. private static readonly int KeySize = 128;
  16. private static readonly int BlockSize = 128;
  17. private static readonly byte[] IvBytes = Encoding.UTF8.GetBytes("0102030405060708");//初始向量
  18. private static int[] InitIA()
  19. {
  20. int len = 256;
  21. int[] a = new int[len];
  22. for (int i = 0; i < len; i++)
  23. {
  24. a[i] = -1;
  25. }
  26. for (int i = 0, iS = CA.Length; i < iS; i++)
  27. {
  28. a[CA[i]] = i;
  29. }
  30. a['='] = 0;
  31. return a;
  32. }
  33. /// <summary>
  34. /// 判断是否base64值
  35. /// </summary>
  36. /// <param name="str"></param>
  37. /// <returns></returns>
  38. public static bool IsBase64Value(string str)
  39. {
  40. // Check special case
  41. int sLen = str != null ? str.Length : 0;
  42. if (sLen == 0)
  43. return false;
  44. // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
  45. // so we don't have to reallocate & copy it later.
  46. int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
  47. for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
  48. {
  49. char currentChar = str[i];
  50. if (currentChar >= IA.Length) {
  51. return false;
  52. }
  53. if (IA[currentChar] < 0) {
  54. sepCnt++;
  55. }
  56. }
  57. // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
  58. if ((sLen - sepCnt) % 4 != 0)
  59. {
  60. return false;
  61. }
  62. return true;
  63. }
  64. /// <summary>
  65. /// 生成滑动窗口
  66. /// </summary>
  67. /// <param name="input">数据</param>
  68. /// <param name="slideSize">分词大小</param>
  69. /// <returns>分词元素</returns>
  70. public static List<string> GetSlideWindows(string input, int slideSize)
  71. {
  72. List<string> windows = new List<string>();
  73. int startIndex = 0;
  74. int endIndex = 0;
  75. int currentWindowSize = 0;
  76. string currentWindow = null;
  77. while (endIndex < input.Length || currentWindowSize > slideSize)
  78. {
  79. bool startsWithLetterOrDigit;
  80. if (currentWindow == null)
  81. {
  82. startsWithLetterOrDigit = false;
  83. }
  84. else
  85. {
  86. startsWithLetterOrDigit = IsLetterOrDigit(currentWindow[0]);
  87. }
  88. if (endIndex == input.Length && !startsWithLetterOrDigit)
  89. {
  90. break;
  91. }
  92. if (currentWindowSize == slideSize && !startsWithLetterOrDigit && IsLetterOrDigit(input[endIndex]))
  93. {
  94. endIndex++;
  95. currentWindow = input.Substring(startIndex, endIndex - startIndex);
  96. currentWindowSize = 5;
  97. }
  98. else
  99. {
  100. if (endIndex != 0)
  101. {
  102. if (startsWithLetterOrDigit)
  103. {
  104. currentWindowSize -= 1;
  105. }
  106. else
  107. {
  108. currentWindowSize -= 2;
  109. }
  110. startIndex++;
  111. }
  112. while (currentWindowSize < slideSize && endIndex < input.Length)
  113. {
  114. char currentChar = input[endIndex];
  115. if (IsLetterOrDigit(currentChar))
  116. {
  117. currentWindowSize += 1;
  118. }
  119. else
  120. {
  121. currentWindowSize += 2;
  122. }
  123. endIndex++;
  124. }
  125. currentWindow = input.Substring(startIndex, endIndex - startIndex);
  126. }
  127. windows.Add(currentWindow);
  128. }
  129. return windows;
  130. }
  131. /// <summary>
  132. /// 判断是否小写字母
  133. /// </summary>
  134. /// <param name="x"></param>
  135. /// <returns></returns>
  136. private static bool IsLetterOrDigit(char x)
  137. {
  138. if (0 <= x && x <= 127)
  139. {
  140. return true;
  141. }
  142. return false;
  143. }
  144. /// <summary>
  145. /// 压缩
  146. /// </summary>
  147. /// <param name="input"></param>
  148. /// <param name="toLength"></param>
  149. /// <returns></returns>
  150. private static byte[] Compress(byte[] input, int toLength)
  151. {
  152. if (toLength < 0)
  153. {
  154. return null;
  155. }
  156. byte[] output = new byte[toLength];
  157. for (int i = 0; i < output.Length; i++)
  158. {
  159. output[i] = 0;
  160. }
  161. for (int i = 0; i < input.Length; i++)
  162. {
  163. int index_output = i % toLength;
  164. output[index_output] ^= input[i];
  165. }
  166. return output;
  167. }
  168. /// <summary>
  169. /// Base64加密
  170. /// </summary>
  171. /// <param name="source">待加密的明文</param>
  172. /// <param name="encode">编码方式</param>
  173. /// <returns></returns>
  174. public static string EncodeBase64(string source, Encoding encode)
  175. {
  176. byte[] bytes = encode.GetBytes(source);
  177. return Convert.ToBase64String(bytes);
  178. }
  179. /// <summary>
  180. /// Base64加密
  181. /// </summary>
  182. /// <param name="source">待加密的明文</param>
  183. /// <returns></returns>
  184. ///
  185. /// <seealso cref="SecurityUtil.EncodeBase64(string,Encoding)">
  186. /// 参看SecurityUtil.EncodeBase64(string,Encoding)方法的说明 </seealso>
  187. public static string EncodeBase64(string source)
  188. {
  189. return EncodeBase64(source, Encoding.UTF8);
  190. }
  191. /// <summary>
  192. /// AES加密
  193. /// </summary>
  194. /// <param name="context">待加密的内容</param>
  195. /// <param name="keyBytes">加密密钥</param>
  196. /// <returns></returns>
  197. public static string AESEncrypt(string context, byte[] keyBytes)
  198. {
  199. RijndaelManaged rijndaelCipher = new RijndaelManaged();
  200. rijndaelCipher.Mode = CipherMode.CBC;
  201. rijndaelCipher.Padding = PaddingMode.PKCS7;
  202. rijndaelCipher.KeySize = KeySize;
  203. rijndaelCipher.BlockSize = KeySize;
  204. // 加密密钥
  205. rijndaelCipher.Key = keyBytes;
  206. rijndaelCipher.IV = IvBytes;
  207. ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
  208. byte[] plainText = Encoding.UTF8.GetBytes(context);
  209. byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
  210. return Convert.ToBase64String(cipherBytes);
  211. }
  212. /// <summary>
  213. /// AES解密
  214. /// </summary>
  215. /// <param name="context"></param>
  216. /// <param name="keyBytes"></param>
  217. /// <returns></returns>
  218. public static string AESDecrypt(string context, byte[] keyBytes)
  219. {
  220. RijndaelManaged rijndaelCipher = new RijndaelManaged();
  221. rijndaelCipher.Mode = CipherMode.CBC;
  222. rijndaelCipher.Padding = PaddingMode.PKCS7;
  223. rijndaelCipher.KeySize = KeySize;
  224. rijndaelCipher.BlockSize = BlockSize;
  225. byte[] encryptedData = Convert.FromBase64String(context);
  226. rijndaelCipher.Key = keyBytes;
  227. rijndaelCipher.IV = IvBytes;
  228. ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
  229. byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
  230. return Encoding.UTF8.GetString(plainText);
  231. }
  232. public static byte[] HmacMD5Encrypt(String encryptText, byte[] encryptKey)
  233. {
  234. HMACMD5 hmac = new HMACMD5(encryptKey);
  235. byte[] bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(encryptText));
  236. return bytes;
  237. }
  238. /// <summary>
  239. /// 生成BASE64(H_MAC)
  240. /// </summary>
  241. /// <param name="encryptText">被签名的字符串</param>
  242. /// <param name="encryptKey">秘钥</param>
  243. /// <returns></returns>
  244. public static string HmacMD5EncryptToBase64(string encryptText, byte[] encryptKey)
  245. {
  246. return Convert.ToBase64String(HmacMD5Encrypt(encryptText, encryptKey));
  247. }
  248. /// <summary>
  249. /// 生成BASE64(H_MAC),压缩H_MAC值
  250. /// </summary>
  251. /// <param name="encryptText"></param>
  252. /// <param name="encryptKey"></param>
  253. /// <param name="compressLen"></param>
  254. /// <returns></returns>
  255. public static String HmacMD5EncryptToBase64(string encryptText, byte[] encryptKey, int compressLen)
  256. {
  257. return Convert.ToBase64String(Compress(HmacMD5Encrypt(encryptText, encryptKey), compressLen));
  258. }
  259. }
  260. }