using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; namespace Pcb.Common { public static class EncryptUtils { //默认密钥向量 private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; private const ulong FC_TAG = 0xFC010203040506CF; private const int BUFFER_SIZE = 128 * 1024; private const string encryptKey = "fs4F22Fs"; /// /// MD5加密 /// /// /// public static string MD5Encrypt(this string values, bool IsLower = true) { //if (!string.IsNullOrEmpty(values)) //{ // return MD5Encrypt(values, encryptKey); //} //return ""; var str = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(values, "MD5"); return IsLower ? str.ToLower() : str; } /// /// MD5加密,加入干扰码 生成32位的加密信息 /// /// /// /// public static string MD5Encrypt(this string values, string passEncrypt) { if (!string.IsNullOrEmpty(values)) { if (!string.IsNullOrEmpty(passEncrypt)) { passEncrypt = encryptKey; } string sEncryptValue = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(values + passEncrypt, "md5"); if (!string.IsNullOrEmpty(sEncryptValue)) { return sEncryptValue.Length > 32 ? sEncryptValue.Substring(0, 32) : sEncryptValue; } } return ""; } /// /// 加密 /// /// /// public static string DESEncrypt(this string Text) { return DESEncrypt(Text, encryptKey); } /// /// DES加密数据 /// /// /// /// public static string DESEncrypt(this string Text, string sKey) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] inputByteArray; inputByteArray = Encoding.Default.GetBytes(Text); des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8)); des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8)); System.IO.MemoryStream ms = new System.IO.MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); StringBuilder ret = new StringBuilder(); foreach (byte b in ms.ToArray()) { ret.AppendFormat("{0:X2}", b); } return ret.ToString(); } /// /// 解密 /// /// /// public static string DESDecrypt(this string Text) { return DESDecrypt(Text, encryptKey); } /// /// 解密数据 /// /// /// /// public static string DESDecrypt(this string Text, string sKey) { if (string.IsNullOrEmpty(Text)) return ""; DESCryptoServiceProvider des = new DESCryptoServiceProvider(); int len; len = Text.Length / 2; byte[] inputByteArray = new byte[len]; int x, i; for (x = 0; x < len; x++) { i = Convert.ToInt32(Text.Substring(x * 2, 2), 16); inputByteArray[x] = (byte)i; } des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8)); des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8)); System.IO.MemoryStream ms = new System.IO.MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); return Encoding.Default.GetString(ms.ToArray()); } /// /// 加密 与论坛交互专用 /// /// /// public static string Encode(string encryptString) { byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8)); byte[] rgbIV = Keys; byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Convert.ToBase64String(mStream.ToArray()); } /// /// 解密 与论坛交互专用 /// /// /// public static string Decode(string decryptString) { try { byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey); byte[] rgbIV = Keys; byte[] inputByteArray = Convert.FromBase64String(decryptString); DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Encoding.UTF8.GetString(mStream.ToArray()); } catch { return ""; } } /// /// 异常处理类 /// public class CryptoHelpException : ApplicationException { public CryptoHelpException(string msg) : base(msg) { } } /// /// 检验两个Byte数组是否相同 /// /// Byte数组 /// Byte数组 /// true-相等 private static bool CheckByteArrays(byte[] b1, byte[] b2) { if (b1.Length == b2.Length) { for (int i = 0; i < b1.Length; ++i) { if (b1[i] != b2[i]) return false; } return true; } return false; } /// /// 创建Rijndael SymmetricAlgorithm /// /// 密码 /// /// 加密对象 private static SymmetricAlgorithm CreateRijndael(string password, byte[] salt) { PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt, "SHA256", 1000); SymmetricAlgorithm sma = Rijndael.Create(); sma.KeySize = 256; sma.Key = pdb.GetBytes(32); sma.Padding = PaddingMode.PKCS7; return sma; } /// /// 加密文件随机数生成 /// private static RandomNumberGenerator rand = new RNGCryptoServiceProvider(); /// /// 生成指定长度的随机Byte数组 /// /// Byte数组长度 /// 随机Byte数组 private static byte[] GenerateRandomBytes(int count) { byte[] bytes = new byte[count]; rand.GetBytes(bytes); return bytes; } /// /// 加密文件 /// /// 待加密文件 /// 加密后输入文件 /// 加密密码 public static bool EncryptFile(string inFile, string outFile, string password) { if (!File.Exists(inFile)) return false; else if (!File.Exists(outFile)) File.Create(outFile); using (FileStream fin = File.OpenRead(inFile), fout = File.OpenWrite(outFile)) { long lSize = fin.Length; // 输入文件长度 int size = (int)lSize; byte[] bytes = new byte[BUFFER_SIZE]; // 缓存 int read = -1; // 输入文件读取数量 int value = 0; // 获取IV和salt byte[] IV = GenerateRandomBytes(16); byte[] salt = GenerateRandomBytes(16); // 创建加密对象 SymmetricAlgorithm sma = CreateRijndael(password, salt); sma.IV = IV; // 在输出文件开始部分写入IV和salt fout.Write(IV, 0, IV.Length); fout.Write(salt, 0, salt.Length); // 创建散列加密 HashAlgorithm hasher = SHA256.Create(); using (CryptoStream cout = new CryptoStream(fout, sma.CreateEncryptor(), CryptoStreamMode.Write), chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) { BinaryWriter bw = new BinaryWriter(cout); bw.Write(lSize); bw.Write(FC_TAG); // 读写字节块到加密流缓冲区 while ((read = fin.Read(bytes, 0, bytes.Length)) != 0) { cout.Write(bytes, 0, read); chash.Write(bytes, 0, read); value += read; } // 关闭加密流 chash.Flush(); chash.Close(); chash.Dispose(); // 读取散列 byte[] hash = hasher.Hash; // 输入文件写入散列 cout.Write(hash, 0, hash.Length); // 关闭文件流 cout.Flush(); cout.Close(); cout.Dispose(); } } return true; } /// /// 解密文件 /// /// 待解密文件 /// 解密后输出文件 /// 解密密码 public static bool DecryptFile(string inFile, string outFile, string password) { if (!File.Exists(inFile)) return false; else if (!File.Exists(outFile)) File.Create(outFile); // 创建打开文件流 using (FileStream fin = File.OpenRead(inFile), fout = File.OpenWrite(outFile)) { int size = (int)fin.Length; byte[] bytes = new byte[BUFFER_SIZE]; int read = -1; int value = 0; int outValue = 0; byte[] IV = new byte[16]; fin.Read(IV, 0, 16); byte[] salt = new byte[16]; fin.Read(salt, 0, 16); SymmetricAlgorithm sma = CreateRijndael(password, salt); sma.IV = IV; value = 32; long lSize = -1; // 创建散列对象, 校验文件 HashAlgorithm hasher = SHA256.Create(); using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read), chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) { // 读取文件长度 BinaryReader br = new BinaryReader(cin); lSize = br.ReadInt64(); ulong tag = br.ReadUInt64(); if (FC_TAG != tag) throw new CryptoHelpException("文件被破坏"); long numReads = lSize / BUFFER_SIZE; long slack = (long)lSize % BUFFER_SIZE; for (int i = 0; i < numReads; ++i) { read = cin.Read(bytes, 0, bytes.Length); fout.Write(bytes, 0, read); chash.Write(bytes, 0, read); value += read; outValue += read; } if (slack > 0) { read = cin.Read(bytes, 0, (int)slack); fout.Write(bytes, 0, read); chash.Write(bytes, 0, read); value += read; outValue += read; } chash.Flush(); chash.Close(); chash.Dispose(); fout.Flush(); fout.Close(); fout.Dispose(); byte[] curHash = hasher.Hash; // 获取比较和旧的散列对象 byte[] oldHash = new byte[hasher.HashSize / 8]; read = cin.Read(oldHash, 0, oldHash.Length); if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash))) throw new CryptoHelpException("文件被破坏"); } if (outValue != lSize) throw new CryptoHelpException("文件大小不匹配"); } return true; } } }