using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
using MyCode.Project.Infrastructure.Exceptions;
namespace MyCode.Project.Infrastructure.Common
{
public class EncryptHelper
{
//DES加密秘钥,要求为8位
private const string desKey = "zhitamal";
//默认密钥向量
private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
//秘钥过期的秒数
private static int expireSecond = 36000;
#region Encrypt(加密,带过期时间)
///
/// DES加密
///
/// 待加密的字符串,未加密成功返回原串
///
public static string Encrypt(string encryptString)
{
var totalSecond = Convert.ToInt64((DateTime.Now - DateTime.Parse("2000-01-01")).TotalSeconds);
encryptString = encryptString + "$$$" + totalSecond;
byte[] rgbKey = Encoding.UTF8.GetBytes(desKey);
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();
string returnStr = Convert.ToBase64String(mStream.ToArray());
returnStr = returnStr.Replace('+', '@');
return System.Web.HttpUtility.UrlEncode(returnStr);
}
#endregion
#region Decrypt(解密,带过期时间)
///
/// DES解密
///
/// 待解密的字符串,未解密成功返回原串
///
public static string Decrypt(string decryptString)
{
decryptString = System.Web.HttpUtility.UrlDecode(decryptString);
decryptString = decryptString.Replace('@', '+');
byte[] rgbKey = Encoding.UTF8.GetBytes(desKey);
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();
var returnStr = Encoding.UTF8.GetString(mStream.ToArray());
var arrStr = returnStr.Split(new char[3] { '$', '$', '$' }, StringSplitOptions.RemoveEmptyEntries);
if (arrStr.Length < 2)
{
throw new BaseException("非法加密字符串:" + decryptString);
}
var totalSecond = Convert.ToInt64(arrStr[1]);
var currentTotalSecond = Convert.ToInt64((DateTime.Now - DateTime.Parse("2000-01-01")).TotalSeconds);
if (currentTotalSecond - totalSecond > expireSecond)
{
throw new BaseException("该加密字符串已过期");
}
return arrStr[0];
}
#endregion
#region GetMD5(获取大写的MD5签名结果)
///
/// 获取大写的MD5签名结果
///
///
///
///
public static string GetMD5(string encypStr, string charset)
{
string retStr;
MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
//创建md5对象
byte[] inputBye;
byte[] outputBye;
//使用GB2312编码方式把字符串转化为字节数组.
try
{
inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
}
catch (Exception ex)
{
inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
}
outputBye = m5.ComputeHash(inputBye);
retStr = System.BitConverter.ToString(outputBye);
retStr = retStr.Replace("-", "").ToUpper();
return retStr;
}
#endregion
#region MD5Encrypt(MD5加密)
///
/// MD5加密
///
/// 需要加密文本
/// 字符编码默认UTF8
///
public static string MD5Encrypt(string encypStr, string charset = "UTF-8")
{
return BitConverter.ToString(MD5.Create().ComputeHash(Encoding.Default.GetBytes(encypStr))).Replace("-", "");
//string retStr;
//MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
////创建md5对象
//byte[] inputBye;
//byte[] outputBye;
////使用GB2312编码方式把字符串转化为字节数组.
//try
//{
// inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
//}
//catch (Exception ex)
//{
// inputBye = Encoding.GetEncoding("UTF-8").GetBytes(encypStr);
//}
//outputBye = m5.ComputeHash(inputBye);
//retStr = System.BitConverter.ToString(outputBye);
//return retStr;
}
#endregion
#region SHA1Hash(SHA加密)
///
/// 加密方法,通过SHA1加密后再转Base64
/// 注意,这个加密属于不可逆的加密,一般用于密码加密使用
///
/// 需要加密的文本
///
public static string SHA1Hash(string input)
{
HashAlgorithm algorithm = SHA1.Create();
return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
#endregion
#region EncryptToSHA1()
///
/// SHA1
///
///
///
public static string EncryptToSHA1(string text)
{
byte[] cleanBytes = Encoding.Default.GetBytes(text);
byte[] hashedBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(cleanBytes);
return BitConverter.ToString(hashedBytes).Replace("-", "");
}
#endregion
#region Base64Encrypt
///
/// Base64加密方法
///
/// 需要加密的文本
///
public static string Base64Encrypt(string input)
{
if (string.IsNullOrWhiteSpace(input)) { return ""; }
return Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
}
#endregion
#region Base64Decrypt
///
/// Base64解密方法
///
/// 需要解密的文本
///
public static string Base64Decrypt(string input)
{
if (string.IsNullOrWhiteSpace(input)) { return ""; }
return Encoding.UTF8.GetString(Convert.FromBase64String(input));
}
#endregion
#region GetParamSrc
private static string GetParamSrc(Dictionary paramsMap)
{
var vDic = (from objDic in paramsMap orderby objDic.Key ascending select objDic);
StringBuilder str = new StringBuilder();
foreach (KeyValuePair kv in vDic)
{
string pkey = kv.Key;
string pvalue = kv.Value;
str.Append(pkey + "=" + pvalue + "&");
}
String result = str.ToString().Substring(0, str.ToString().Length - 1);
return result;
}
public static string GetSign(Dictionary paramsMap, string signKey)
{
var paramstr = GetParamSrc(paramsMap);
paramstr = paramstr + $"&signKey={signKey}";
return MD5Encrypt(paramstr).Replace("-","").ToLower();
}
#endregion
#region AES_Decrypt(解密)
private static byte[] AES_Decrypt(String Input, byte[] Iv, byte[] Key)
{
#if NET45
RijndaelManaged aes = new RijndaelManaged();
#else
SymmetricAlgorithm aes = Aes.Create();
#endif
aes.KeySize = 128;//原始:256
aes.BlockSize = 128;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = Key;
aes.IV = Iv;
var decrypt = aes.CreateDecryptor(aes.Key, aes.IV);
byte[] xBuff = null;
//using (ICryptoTransform decrypt = aes.CreateDecryptor(aes.Key, aes.IV) /*aes.CreateDecryptor()*/)
//{
// var src = Convert.FromBase64String(Input);
// byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
// return dest;
// //return Encoding.UTF8.GetString(dest);
//}
try
{
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
{
//cs.Read(decryptBytes, 0, decryptBytes.Length);
//cs.Close();
//ms.Close();
//cs.FlushFinalBlock();//用于解决第二次获取小程序Session解密出错的情况
byte[] xXml = Convert.FromBase64String(Input);
byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32];
Array.Copy(xXml, msg, xXml.Length);
cs.Write(xXml, 0, xXml.Length);
}
//cs.Dispose();
xBuff = decode2(ms.ToArray());
}
}
catch (System.Security.Cryptography.CryptographicException e)
{
//Padding is invalid and cannot be removed.
Console.WriteLine("===== CryptographicException =====");
using (var ms = new MemoryStream())
{
//cs 不自动释放,用于避免“Padding is invalid and cannot be removed”的错误 —— 2019.07.27 Jeffrey
var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write);
{
//cs.Read(decryptBytes, 0, decryptBytes.Length);
//cs.Close();
//ms.Close();
//cs.FlushFinalBlock();//用于解决第二次获取小程序Session解密出错的情况
byte[] xXml = Convert.FromBase64String(Input);
byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32];
Array.Copy(xXml, msg, xXml.Length);
cs.Write(xXml, 0, xXml.Length);
}
//cs.Dispose();
xBuff = decode2(ms.ToArray());
}
}
return xBuff;
}
private static byte[] decode2(byte[] decrypted)
{
int pad = (int)decrypted[decrypted.Length - 1];
if (pad < 1 || pad > 32)
{
pad = 0;
}
byte[] res = new byte[decrypted.Length - pad];
Array.Copy(decrypted, 0, res, 0, decrypted.Length - pad);
return res;
}
#endregion
#region DecodeEncryptedData(解密小程序的加密方式)
///
/// 解密所有消息的基础方法
///
/// 储存在 SessionBag 中的当前用户 会话 SessionKey
/// 接口返回数据中的 encryptedData 参数
/// 接口返回数据中的 iv 参数,对称解密算法初始向量
// /
public static string DecodeEncryptedData(string sessionKey, string encryptedData, string iv)
{
var aesCipher = Convert.FromBase64String(encryptedData);
var aesKey = Convert.FromBase64String(sessionKey);
var aesIV = Convert.FromBase64String(iv);
var result = AES_Decrypt(encryptedData, aesIV, aesKey);
var resultStr = Encoding.UTF8.GetString(result);
return resultStr;
}
#endregion
}
}