Files
YunTongJackYunTask/Reportapi/MyCode.Project.Infrastructure/Common/EncryptHelper.cs
2025-07-04 09:50:02 +08:00

344 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
/// <summary>
/// DES加密
/// </summary>
/// <param name="encryptString">待加密的字符串,未加密成功返回原串</param>
/// <returns></returns>
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()
/// <summary>
/// DES解密
/// </summary>
/// <param name="decryptString">待解密的字符串,未解密成功返回原串</param>
/// <returns></returns>
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签名结果)
/// <summary>
/// 获取大写的MD5签名结果
/// </summary>
/// <param name="encypStr"></param>
/// <param name="charset"></param>
/// <returns></returns>
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加密)
/// <summary>
/// MD5加密
/// </summary>
/// <param name="encypStr">需要加密文本</param>
/// <param name="charset">字符编码默认UTF8</param>
/// <returns></returns>
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加密)
/// <summary>
/// 加密方法通过SHA1加密后再转Base64
/// 注意,这个加密属于不可逆的加密,一般用于密码加密使用
/// </summary>
/// <param name="input">需要加密的文本</param>
/// <returns></returns>
public static string SHA1Hash(string input)
{
HashAlgorithm algorithm = SHA1.Create();
return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
#endregion
#region EncryptToSHA1()
/// <summary>
/// SHA1
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
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
/// <summary>
/// Base64加密方法
/// </summary>
/// <param name="input">需要加密的文本</param>
/// <returns></returns>
public static string Base64Encrypt(string input)
{
if (string.IsNullOrWhiteSpace(input)) { return ""; }
return Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
}
#endregion
#region Base64Decrypt
/// <summary>
/// Base64解密方法
/// </summary>
/// <param name="input">需要解密的文本</param>
/// <returns></returns>
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<string, string> paramsMap)
{
var vDic = (from objDic in paramsMap orderby objDic.Key ascending select objDic);
StringBuilder str = new StringBuilder();
foreach (KeyValuePair<string, string> 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<string, string> 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()
/// <summary>
/// 解密所有消息的基础方法
/// </summary>
/// <param name = "sessionKey" > 储存在 SessionBag 中的当前用户 会话 SessionKey</param>
/// <param name = "encryptedData" > 接口返回数据中的 encryptedData 参数</param>
/// <param name = "iv" > 接口返回数据中的 iv 参数,对称解密算法初始向量</param>
// / <returns></returns>
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
}
}