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();
}
}
}