using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography; using System.IO; namespace CommonUtil { /// /// 安全工具类 /// public abstract class SecurityUtil { private static readonly char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".ToCharArray(); private static readonly int[] IA = InitIA(); private static readonly int KeySize = 128; private static readonly int BlockSize = 128; private static readonly byte[] IvBytes = Encoding.UTF8.GetBytes("0102030405060708");//初始向量 /// /// 初始化 /// /// private static int[] InitIA() { int len = 256; int[] a = new int[len]; for (int i = 0; i < len; i++) { a[i] = -1; } for (int i = 0, iS = CA.Length; i < iS; i++) { a[CA[i]] = i; } a['='] = 0; return a; } /// /// 判断是否base64值 /// /// /// public static bool IsBase64Value(string str) { // Check special case int sLen = str != null ? str.Length : 0; if (sLen == 0) return false; // Count illegal characters (including '\r', '\n') to know what size the returned array will be, // so we don't have to reallocate & copy it later. int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) 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. { char currentChar = str[i]; if (currentChar >= IA.Length) { return false; } if (IA[currentChar] < 0) { sepCnt++; } } // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. if ((sLen - sepCnt) % 4 != 0) { return false; } return true; } /// /// 生成滑动窗口 /// /// 数据 /// 分词大小 /// 分词元素 public static List GetSlideWindows(string input, int slideSize) { List windows = new List(); int startIndex = 0; int endIndex = 0; int currentWindowSize = 0; string currentWindow = null; while (endIndex < input.Length || currentWindowSize > slideSize) { bool startsWithLetterOrDigit; if (currentWindow == null) { startsWithLetterOrDigit = false; } else { startsWithLetterOrDigit = IsLetterOrDigit(currentWindow[0]); } if (endIndex == input.Length && !startsWithLetterOrDigit) { break; } if (currentWindowSize == slideSize && !startsWithLetterOrDigit && IsLetterOrDigit(input[endIndex])) { endIndex++; currentWindow = input.Substring(startIndex, endIndex - startIndex); currentWindowSize = 5; } else { if (endIndex != 0) { if (startsWithLetterOrDigit) { currentWindowSize -= 1; } else { currentWindowSize -= 2; } startIndex++; } while (currentWindowSize < slideSize && endIndex < input.Length) { char currentChar = input[endIndex]; if (IsLetterOrDigit(currentChar)) { currentWindowSize += 1; } else { currentWindowSize += 2; } endIndex++; } currentWindow = input.Substring(startIndex, endIndex - startIndex); } windows.Add(currentWindow); } return windows; } /// /// 判断是否小写字母 /// /// /// private static bool IsLetterOrDigit(char x) { if (0 <= x && x <= 127) { return true; } return false; } /// /// 压缩 /// /// /// /// private static byte[] Compress(byte[] input, int toLength) { if (toLength < 0) { return null; } byte[] output = new byte[toLength]; for (int i = 0; i < output.Length; i++) { output[i] = 0; } for (int i = 0; i < input.Length; i++) { int index_output = i % toLength; output[index_output] ^= input[i]; } return output; } /// /// Base64加密 /// /// 待加密的明文 /// 编码方式 /// public static string EncodeBase64(string source, Encoding encode) { byte[] bytes = encode.GetBytes(source); return Convert.ToBase64String(bytes); } /// /// Base64加密 /// /// 待加密的明文 /// /// /// /// 参看SecurityUtil.EncodeBase64(string,Encoding)方法的说明 public static string EncodeBase64(string source) { return EncodeBase64(source, Encoding.UTF8); } /// /// DES加密 /// /// 需要加密的字符串 /// 密钥 /// 偏移量 /// 加密后的密文 public static string DesEncrypt(string str, string key, string iv) { if (str.IsNullOrEmpty() || key.IsNullOrEmpty() || iv.IsNullOrEmpty()) { return null; } var bKey = new Byte[8]; Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(8)), bKey, 8); var bIv = new Byte[8]; Array.Copy(Encoding.UTF8.GetBytes(iv.PadRight(8)), bIv, 8); var oldbytes = Encoding.UTF8.GetBytes(str); using (var dcsp = new DESCryptoServiceProvider())//using(){}:{}语句执行完后会将()中的释放,相当于dcsp.Dispose(); { using (var ms = new MemoryStream()) { var cs = new CryptoStream(ms, dcsp.CreateEncryptor(bKey, bIv), CryptoStreamMode.Write); cs.Write(oldbytes, 0, oldbytes.Length); cs.FlushFinalBlock(); var newbytes = ms.ToArray(); cs.Dispose();//释放cs return Convert.ToBase64String(newbytes); } } } /// /// DES解密 /// /// 需要解密的密文 /// 密钥 /// 偏移量 /// 解密后的字符串 public static string DesDecrypt(string str, string key, string iv) { if (str.IsNullOrEmpty() || key.IsNullOrEmpty() || key.IsNullOrEmpty()) { return null; } var bKey = new Byte[8]; Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(8)), bKey, 8); var bIv = new Byte[8]; Array.Copy(Encoding.UTF8.GetBytes(iv.PadRight(8)), bIv, 8); var oldbytes = Convert.FromBase64String(str); using (var dcsp = new DESCryptoServiceProvider()) { using (var ms = new MemoryStream()) { var cs = new CryptoStream(ms, dcsp.CreateDecryptor(bKey, bIv), CryptoStreamMode.Write); cs.Write(oldbytes, 0, oldbytes.Length); cs.FlushFinalBlock(); var newBytes = ms.ToArray(); cs.Dispose(); return Encoding.UTF8.GetString(newBytes); } } } /// /// AES加密 /// /// 待加密的内容 /// 加密密钥 /// public static string AesEncrypt(string context, byte[] keyBytes) { RijndaelManaged rijndaelCipher = new RijndaelManaged(); rijndaelCipher.Mode = CipherMode.CBC; rijndaelCipher.Padding = PaddingMode.PKCS7; rijndaelCipher.KeySize = KeySize; rijndaelCipher.BlockSize = KeySize; // 加密密钥 rijndaelCipher.Key = keyBytes; rijndaelCipher.IV = IvBytes; ICryptoTransform transform = rijndaelCipher.CreateEncryptor(); byte[] plainText = Encoding.UTF8.GetBytes(context); byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length); return Convert.ToBase64String(cipherBytes); } /// /// AES解密 /// /// /// /// public static string AesDecrypt(string context, byte[] keyBytes) { RijndaelManaged rijndaelCipher = new RijndaelManaged(); rijndaelCipher.Mode = CipherMode.CBC; rijndaelCipher.Padding = PaddingMode.PKCS7; rijndaelCipher.KeySize = KeySize; rijndaelCipher.BlockSize = BlockSize; byte[] encryptedData = Convert.FromBase64String(context); rijndaelCipher.Key = keyBytes; rijndaelCipher.IV = IvBytes; ICryptoTransform transform = rijndaelCipher.CreateDecryptor(); byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length); return Encoding.UTF8.GetString(plainText); } /// /// Aes加密 /// /// 需要加密的字符串 /// 密钥,长度不够时空格补齐,超过时从左截取 /// 偏移量,长度不够时空格补齐,超过时从左截取 /// 秘钥长度,16 24 32 /// 加密模式 /// 填充方式 /// public static string AesEncrypt(string str, string key, string iv, int keyLenth = 16, CipherMode aesMode = CipherMode.CBC, PaddingMode aesPadding = PaddingMode.PKCS7) { //对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB) 。 if (str.IsNullOrEmpty() || key.IsNullOrEmpty() || iv.IsNullOrEmpty()) { return null; } if (!new List { 16, 24, 32 }.Contains(keyLenth)) { return null;//密钥的长度,16位密钥 = 128位,24位密钥 = 192位,32位密钥 = 256位。 } var oldBytes = Encoding.UTF8.GetBytes(str); key = key.Length > keyLenth ? key.Substring(0, keyLenth) : key.Length < keyLenth ? key.PadRight(keyLenth) : key; iv = iv.Length > 16 ? iv.Substring(0, 16) : iv.Length < 16 ? iv.PadRight(16) : iv; var bKey = Encoding.UTF8.GetBytes(key); var bIv = Encoding.UTF8.GetBytes(iv); var rijalg = new RijndaelManaged { Mode = aesMode, Padding = aesPadding, Key = bKey, IV = bIv, }; var decryptor = rijalg.CreateEncryptor(rijalg.Key, rijalg.IV); var rtByte = decryptor.TransformFinalBlock(oldBytes, 0, oldBytes.Length); return Convert.ToBase64String(rtByte); } /// /// Aes解密 /// /// 需要解密的字符串 /// 密钥,长度不够时空格补齐,超过时从左截取 /// 偏移量,长度不够时空格补齐,超过时从左截取 /// 秘钥长度,16 24 32 /// 解密模式 /// 填充方式 /// public static string AesDecrypt(string str, string key, string iv, int keyLenth = 16, CipherMode aesMode = CipherMode.CBC, PaddingMode aesPadding = PaddingMode.PKCS7) { if (str.IsNullOrEmpty() || key.IsNullOrEmpty() || iv.IsNullOrEmpty()) { return null; } if (!new List { 16, 24, 32 }.Contains(keyLenth)) { return null;//密钥的长度,16位密钥 = 128位,24位密钥 = 192位,32位密钥 = 256位。 } var oldBytes = Convert.FromBase64String(str); key = key.Length > keyLenth ? key.Substring(0, keyLenth) : key.Length < keyLenth ? key.PadRight(keyLenth) : key; iv = iv.Length > 16 ? iv.Substring(0, 16) : iv.Length < 16 ? iv.PadRight(16) : iv; var bKey = Encoding.UTF8.GetBytes(key); var bIv = Encoding.UTF8.GetBytes(iv); var rijalg = new RijndaelManaged { Mode = aesMode, Padding = aesPadding, Key = bKey, IV = bIv, }; var decryptor = rijalg.CreateDecryptor(rijalg.Key, rijalg.IV); var rtByte = decryptor.TransformFinalBlock(oldBytes, 0, oldBytes.Length); return Encoding.UTF8.GetString(rtByte); } /// /// MD5加密 /// /// 明文 /// 密文采用Base64还是等效16进制字符串 /// 密文 public static string MD5Encrypt(string str, bool isBase64 = false) { if (str.IsNullOrEmpty()) { return null; } var oldBytes = Encoding.UTF8.GetBytes(str); MD5 md5 = new MD5CryptoServiceProvider(); var newBytes = md5.ComputeHash(oldBytes); var result = isBase64 ? Convert.ToBase64String(newBytes) : BitConverter.ToString(newBytes).Replace("-", ""); return result; } /// /// MD5加密 /// /// 明文 /// 密文 public static byte[] MD5Encrypt(string str) { MD5 md5 = MD5.Create(); byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); return bytes; } /// /// HmacMD5加密 /// /// /// /// public static byte[] HmacMD5Encrypt(String encryptText, byte[] encryptKey) { HMACMD5 hmac = new HMACMD5(encryptKey); byte[] bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(encryptText)); return bytes; } /// /// 生成BASE64(H_MAC) /// /// 被签名的字符串 /// 秘钥 /// public static string HmacMD5EncryptToBase64(string encryptText, byte[] encryptKey) { return Convert.ToBase64String(HmacMD5Encrypt(encryptText, encryptKey)); } /// /// 生成BASE64(H_MAC),压缩H_MAC值 /// /// /// /// /// public static string HmacMD5EncryptToBase64(string encryptText, byte[] encryptKey, int compressLen) { return Convert.ToBase64String(Compress(HmacMD5Encrypt(encryptText, encryptKey), compressLen)); } /// /// 签名.MD5加密,32位大写 /// /// /// /// public static string SignRequest(IDictionary parameters, string secret) { // 第一步:把字典按Key的字母顺序排序 IDictionary sortedParams = new SortedDictionary(parameters, StringComparer.Ordinal); // 第二步:把所有参数名和参数值串在一起 StringBuilder query = new StringBuilder(); query.Append(secret); foreach (KeyValuePair kv in sortedParams) { if (!string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value)) { query.Append(kv.Key).Append(kv.Value); } } query.Append(secret); // 第三步:MD5加密 byte[] bytes = MD5Encrypt(query.ToString()); // 第四步:把二进制转化为大写的十六进制 StringBuilder result = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { result.Append(bytes[i].ToString("X2")); } return result.ToString(); } } }