using System.Text;
using System;
using System.Security.Cryptography;
using System.Linq;
using RSAExtensions;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
namespace Business.Core.Utilities
{
///
/// 加密操作
///
public static class Encrypt
{
#region Md5加密
///
/// Md5加密,返回16位结果
///
/// 值
public static string Md5By16(string value)
{
return Md5By16(value, Encoding.UTF8);
}
///
/// Md5加密,返回16位结果
///
/// 值
/// 字符编码
public static string Md5By16(string value, Encoding encoding)
{
return Md5(value, encoding, 4, 8);
}
///
/// Md5加密
///
private static string Md5(string value, Encoding encoding, int? startIndex, int? length)
{
if (string.IsNullOrWhiteSpace(value))
return string.Empty;
var md5 = MD5.Create();
string result;
try
{
var hash = md5.ComputeHash(encoding.GetBytes(value));
result = startIndex == null ? BitConverter.ToString(hash) : BitConverter.ToString(hash, startIndex.SafeValue(), length.SafeValue());
}
finally
{
md5.Clear();
}
return result.Replace("-", "");
}
///
/// Md5加密,返回32位结果
///
/// 值
public static string Md5By32(string value)
{
return Md5By32(value, Encoding.UTF8);
}
///
/// Md5加密,返回32位结果
///
/// 值
/// 字符编码
public static string Md5By32(string value, Encoding encoding)
{
return Md5(value, encoding, null, null);
}
#endregion
#region DES加密
///
/// DES密钥,24位字符串
///
private static string DesKey = "#s^un2ye21fcv%|f0XpR,+vh";
///
/// DES加密
///
/// 待加密的值
public static string DesEncrypt(object value)
{
return DesEncrypt(value, DesKey);
}
///
/// DES加密
///
/// 待加密的值
/// 密钥,24位
/// 编码
/// 加密模式
/// 填充模式
public static string DesEncrypt(object value, string key, Encoding? encoding = null, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
string text = value.SafeString();
if (ValidateDes(text, key) == false)
return string.Empty;
using var transform = CreateDesProvider(key, cipherMode, paddingMode).CreateEncryptor();
return GetEncryptResult(text, encoding, transform);
}
///
/// 验证Des加密参数
///
private static bool ValidateDes(string text, string key)
{
if (text.IsEmpty() || key.IsEmpty())
return false;
return key.Length == 24;
}
///
/// 创建Des加密服务提供程序
///
private static TripleDES CreateDesProvider(string key, CipherMode cipherMode, PaddingMode paddingMode)
{
var result = TripleDES.Create();
result.Key = Encoding.ASCII.GetBytes(key);
result.Mode = cipherMode;
result.Padding = paddingMode;
return result;
}
///
/// 获取加密结果
///
private static string GetEncryptResult(string value, Encoding? encoding, ICryptoTransform transform)
{
encoding ??= Encoding.UTF8;
var bytes = encoding.GetBytes(value);
var result = transform.TransformFinalBlock(bytes, 0, bytes.Length);
return System.Convert.ToBase64String(result);
}
///
/// DES解密
///
/// 加密后的值
public static string DesDecrypt(object value)
{
return DesDecrypt(value, DesKey);
}
///
/// DES解密
///
/// 加密后的值
/// 密钥,24位
/// 编码
/// 加密模式
/// 填充模式
public static string DesDecrypt(object value, string key, Encoding? encoding = null, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
string text = value.SafeString();
if (!ValidateDes(text, key))
return string.Empty;
using var transform = CreateDesProvider(key, cipherMode, paddingMode).CreateDecryptor();
return GetDecryptResult(text, encoding, transform);
}
///
/// 获取解密结果
///
private static string GetDecryptResult(string value, Encoding? encoding, ICryptoTransform transform)
{
encoding ??= Encoding.UTF8;
var bytes = System.Convert.FromBase64String(value);
var result = transform.TransformFinalBlock(bytes, 0, bytes.Length);
return encoding.GetString(result);
}
#endregion
#region AES加密
///
/// 128位0向量
///
private static byte[] _iv;
///
/// 128位0向量
///
private static byte[] Iv
{
get
{
if (_iv == null)
{
var size = 16;
_iv = new byte[size];
for (int i = 0; i < size; i++)
_iv[i] = 0;
}
return _iv;
}
}
///
/// AES密钥
///
private static string AesKey = "QaP1AF8utIarcBqdhYTZpVGbiNQ9M6IL";
///
/// AES加密
///
/// 待加密的值
public static string AesEncrypt(string value)
{
return AesEncrypt(value, AesKey);
}
///
/// AES加密
///
/// 待加密的值
/// 密钥
/// 编码
/// 加密模式
/// 填充模式
/// 初始化向量
public static string AesEncrypt(string value, string key, Encoding? encoding = null, CipherMode cipherMode = CipherMode.CBC, PaddingMode paddingMode = PaddingMode.PKCS7, byte[]? iv = null)
{
if (value.IsEmpty() || key.IsEmpty())
return string.Empty;
iv ??= Iv;
var aes = CreateAes(key, cipherMode, paddingMode, iv);
using var transform = aes.CreateEncryptor(aes.Key, aes.IV);
return GetEncryptResult(value, encoding, transform);
}
///
/// 创建Aes
///
private static Aes CreateAes(string key, CipherMode cipherMode, PaddingMode paddingMode, byte[] iv)
{
var result = Aes.Create();
result.Key = Encoding.ASCII.GetBytes(key);
result.Mode = cipherMode;
result.Padding = paddingMode;
result.IV = iv;
return result;
}
///
/// AES解密
///
/// 加密后的值
public static string AesDecrypt(string value)
{
return AesDecrypt(value, AesKey);
}
///
/// AES解密
///
/// 加密后的值
/// 密钥
/// 编码
/// 加密模式
/// 填充模式
/// 初始化向量
public static string AesDecrypt(string value, string key, Encoding? encoding = null, CipherMode cipherMode = CipherMode.CBC, PaddingMode paddingMode = PaddingMode.PKCS7, byte[]? iv = null)
{
if (value.IsEmpty() || key.IsEmpty())
return string.Empty;
iv ??= Iv;
var aes = CreateAes(key, cipherMode, paddingMode, iv);
using var transform = aes.CreateDecryptor(aes.Key, aes.IV);
return GetDecryptResult(value, encoding, transform);
}
#endregion
#region HmacSha256加密
///
/// HMACSHA256加密
///
/// 值
/// 密钥
/// 字符编码
public static string HmacSha256(string value, string key, Encoding? encoding = null)
{
if (value.IsEmpty() || key.IsEmpty())
return string.Empty;
encoding ??= Encoding.UTF8;
var sha256 = new HMACSHA256(Encoding.ASCII.GetBytes(key));
var hash = sha256.ComputeHash(encoding.GetBytes(value));
return string.Join("", hash.ToList().Select(t => t.ToString("x2")).ToArray());
}
#endregion
#region RSA加密
///
/// RSA签名
///
/// 待加密的值
/// 私钥
/// 编码
/// 加密算法,默认值: HashAlgorithmName.SHA1
/// Rsa密钥类型,默认值: Pkcs1
public static string RsaSign(string value, string privateKey, Encoding? encoding = null, HashAlgorithmName? hashAlgorithm = null, RSAKeyType rsaKeyType = RSAKeyType.Pkcs1)
{
if (value.IsEmpty() || privateKey.IsEmpty())
return string.Empty;
var rsa = RSA.Create();
ImportPrivateKey(rsa, privateKey, rsaKeyType);
encoding ??= Encoding.UTF8;
hashAlgorithm ??= HashAlgorithmName.SHA1;
var result = rsa.SignData(encoding.GetBytes(value), hashAlgorithm.Value, RSASignaturePadding.Pkcs1);
return System.Convert.ToBase64String(result);
}
///
/// 导入私钥
///
private static void ImportPrivateKey(RSA rsa, string privateKey, RSAKeyType rsaKeyType)
{
rsa.ImportPrivateKey(rsaKeyType, privateKey);
}
///
/// Rsa验签
///
/// 待验签的值
/// 公钥
/// 签名
/// 编码
/// 加密算法,默认值: HashAlgorithmName.SHA1
public static bool RsaVerify(string value, string publicKey, string sign, Encoding? encoding = null, HashAlgorithmName? hashAlgorithm = null)
{
if (value.IsEmpty() || publicKey.IsEmpty() || sign.IsEmpty())
return false;
var rsa = RSA.Create();
ImportPublicKey(rsa, publicKey);
encoding ??= Encoding.UTF8;
var signData = System.Convert.FromBase64String(sign);
hashAlgorithm ??= HashAlgorithmName.SHA1;
return rsa.VerifyData(encoding.GetBytes(value), signData, hashAlgorithm.Value, RSASignaturePadding.Pkcs1);
}
///
/// 导入公钥
///
private static void ImportPublicKey(RSA rsa, string publicKey)
{
var key = System.Convert.FromBase64String(publicKey);
rsa.ImportSubjectPublicKeyInfo(key, out _);
}
///
/// RSA加密
///
/// 待加密的值
/// 公钥
public static string RsaEncrypt(string value, string publicKey)
{
if (value.IsEmpty() || publicKey.IsEmpty())
return string.Empty;
var rsa = RSA.Create();
ImportPublicKey(rsa, publicKey);
return rsa.EncryptBigData(value, RSAEncryptionPadding.Pkcs1);
}
///
/// RSA解密
///
/// 加密后的值
/// 私钥
public static string RsaDecrypt(string value, string privateKey)
{
if (value.IsEmpty() || privateKey.IsEmpty())
return string.Empty;
var rsa = RSA.Create();
ImportPrivateKey(rsa, privateKey, RSAKeyType.Pkcs1);
return rsa.DecryptBigData(value, RSAEncryptionPadding.Pkcs1);
}
///
/// 密码解密之后的mongo连接地址
///
public static string GetMongoDBConnectionSM4DecryptString(string connectionString)
{
if (connectionString.IndexOf("@") > 0)
{
var strAry = connectionString.Split("@");
var userInfo = strAry[0].Substring(10).Split(new char[1] { ':' });
string userInfoStr = string.Format("{0}:{1}", userInfo[0], AesDecrypt(userInfo[1]));
return string.Format("mongodb://{0}@{1}", userInfoStr, strAry[1]);
}
else
{
return connectionString;
}
}
#endregion
}
}