前言
在我們日常開發工作中,為了資料安全問題對資料加密、解密是必不可少的。加密方式有很多種如常見的AES,RSA,MD5,SAH1,SAH256,DES等,這時候假如我們有一個封裝的對應加密解密工具類可以直接呼叫,那這樣可以節省不少的開發時間。今天推薦一款實用的.NET Core加密解密工具類庫:NETCore.Encrypt。
專案介紹
NETCore.Encrypt是.NET Core加密解密工具類庫,包括AES、RSA、MD5、SHA1、DES、SHA256、SHA384、SHA512等更多功能。
專案原始碼
MD5加密
封裝方法
#region MD5
/// <summary>
/// MD5 hash
/// </summary>
/// <param name="srcString">The string to be encrypted.</param>
/// <param name="length">The length of hash result , default value is <see cref="MD5Length.L32"/>.</param>
/// <returns></returns>
public static string Md5(string srcString, MD5Length length = MD5Length.L32)
{
Check.Argument.IsNotEmpty(srcString, nameof(srcString));
string str_md5_out = string.Empty;
using (MD5 md5 = MD5.Create())
{
byte[] bytes_md5_in = Encoding.UTF8.GetBytes(srcString);
byte[] bytes_md5_out = md5.ComputeHash(bytes_md5_in);
str_md5_out = length == MD5Length.L32
? BitConverter.ToString(bytes_md5_out)
: BitConverter.ToString(bytes_md5_out, 4, 8);
str_md5_out = str_md5_out.Replace("-", "");
return str_md5_out;
}
}
#endregion
呼叫結果
public static void MD5_Test()
{
var srcString = "追逐時光者";
var hashed = EncryptProvider.Md5(srcString);
Console.WriteLine("MD5加密結果:" + hashed);
}
RSA加密&解密
封裝方法
/// <summary>
/// RSA encrypt
/// </summary>
/// <param name="publicKey">public key</param>
/// <param name="srcString">src string</param>
/// <param name="padding">rsa encryptPadding <see cref="RSAEncryptionPadding"/> RSAEncryptionPadding.Pkcs1 for linux/mac openssl </param>
/// <param name="isPemKey">set key is pem format,default is false</param>
/// <returns>encrypted string</returns>
public static string RSAEncrypt(string publicKey, string srcString, RSAEncryptionPadding padding, bool isPemKey = false)
{
Check.Argument.IsNotEmpty(publicKey, nameof(publicKey));
Check.Argument.IsNotEmpty(srcString, nameof(srcString));
Check.Argument.IsNotNull(padding, nameof(padding));
RSA rsa;
if (isPemKey)
{
rsa = RsaProvider.FromPem(publicKey);
}
else
{
rsa = RSA.Create();
rsa.FromJsonString(publicKey);
}
using (rsa)
{
var maxLength = GetMaxRsaEncryptLength(rsa, padding);
var rawBytes = Encoding.UTF8.GetBytes(srcString);
if (rawBytes.Length > maxLength)
{
throw new OutofMaxlengthException($"'{srcString}' is out of max encrypt length {maxLength}", maxLength, rsa.KeySize, padding);
}
byte[] encryptBytes = rsa.Encrypt(rawBytes, padding);
return encryptBytes.ToHexString();
}
}
/// <summary>
/// RSA decrypt
/// </summary>
/// <param name="publicKey">public key</param>
/// <param name="srcString">src string</param>
/// <param name="padding">rsa encryptPadding <see cref="RSAEncryptionPadding"/> RSAEncryptionPadding.Pkcs1 for linux/mac openssl </param>
/// <param name="isPemKey">set key is pem format,default is false</param>
/// <returns>encrypted string</returns>
public static string RSADecrypt(string privateKey, string srcString, RSAEncryptionPadding padding, bool isPemKey = false)
{
Check.Argument.IsNotEmpty(privateKey, nameof(privateKey));
Check.Argument.IsNotEmpty(srcString, nameof(srcString));
Check.Argument.IsNotNull(padding, nameof(padding));
RSA rsa;
if (isPemKey)
{
rsa = RsaProvider.FromPem(privateKey);
}
else
{
rsa = RSA.Create();
rsa.FromJsonString(privateKey);
}
using (rsa)
{
byte[] srcBytes = srcString.ToBytes();
byte[] decryptBytes = rsa.Decrypt(srcBytes, padding);
return Encoding.UTF8.GetString(decryptBytes);
}
}
呼叫結果
#region Rsa加密&解密
public static void Rsa_Encrypt_Decrypt_Test(RsaSize size)
{
var rsaKey = EncryptProvider.CreateRsaKey(size);
var srcString = "追逐時光者";
var encrypted = EncryptProvider.RSAEncrypt(rsaKey.PublicKey, srcString);
Console.WriteLine("RSA加密結果:" + encrypted);
Console.WriteLine("\r\n");
var decrypted = EncryptProvider.RSADecrypt(rsaKey.PrivateKey, encrypted);
Console.WriteLine("RSA解密結果:" + decrypted);
}
#endregion
DES加密&解密
封裝方法
/// <summary>
/// DES encrypt
/// </summary>
/// <param name="data">Raw data byte array</param>
/// <param name="key">Key, requires 24 bits</param>
/// <param name="vector">IV,requires 8 bits</param>
/// <returns>Encrypted byte array</returns>
public static byte[] DESEncrypt(byte[] data, string key, string vector)
{
Check.Argument.IsNotEmpty(data, nameof(data));
Check.Argument.IsNotEmpty(key, nameof(key));
Check.Argument.IsEqualLength(key.Length, 24, nameof(key));
Check.Argument.IsNotEmpty(vector, nameof(vector));
Check.Argument.IsEqualLength(vector.Length, 8, nameof(vector));
return DESEncrypt(data, key, CipherMode.CBC, vector);
}
/// <summary>
/// DES encrypt
/// </summary>
/// <param name="data">Raw data</param>
/// <param name="key">Key, requires 24 bits</param>
/// <param name="cipherMode"><see cref="CipherMode"/></param>
/// <param name="paddingMode"><see cref="PaddingMode"/> default is PKCS7</param>
/// <param name="vector">IV,requires 8 bits</param>
/// <returns>Encrypted byte array</returns>
private static byte[] DESEncrypt(byte[] data, string key, CipherMode cipherMode, string vector = "", PaddingMode paddingMode = PaddingMode.PKCS7)
{
Check.Argument.IsNotEmpty(data, nameof(data));
Check.Argument.IsNotEmpty(key, nameof(key));
Check.Argument.IsEqualLength(key.Length, 24, nameof(key));
using (MemoryStream Memory = new MemoryStream())
{
using (TripleDES des = TripleDES.Create())
{
byte[] plainBytes = data;
byte[] bKey = new byte[24];
Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);
des.Mode = cipherMode;
des.Padding = paddingMode;
des.Key = bKey;
if (cipherMode == CipherMode.CBC)
{
byte[] bVector = new byte[8];
Array.Copy(Encoding.UTF8.GetBytes(vector.PadRight(bVector.Length)), bVector, bVector.Length);
des.IV = bVector;
}
using (CryptoStream cryptoStream = new CryptoStream(Memory, des.CreateEncryptor(), CryptoStreamMode.Write))
{
try
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
return Memory.ToArray();
}
catch (Exception ex)
{
return null;
}
}
}
}
}
/// <summary>
/// DES encrypt
/// </summary>
/// <param name="data">Raw data byte array</param>
/// <param name="key">Key, requires 24 bits</param>
/// <param name="vector">IV,requires 8 bits</param>
/// <returns>Encrypted byte array</returns>
public static byte[] DESDecrypt(byte[] data, string key, string vector)
{
Check.Argument.IsNotEmpty(data, nameof(data));
Check.Argument.IsNotEmpty(key, nameof(key));
Check.Argument.IsEqualLength(key.Length, 24, nameof(key));
Check.Argument.IsNotEmpty(vector, nameof(vector));
Check.Argument.IsEqualLength(vector.Length, 8, nameof(vector));
return DESDecrypt(data, key, CipherMode.CBC, vector);
}
/// <summary>
/// DES decrypt
/// </summary>
/// <param name="data">Encrypted data</param>
/// <param name="key">Key, requires 24 bits</param>
/// <param name="cipherMode"><see cref="CipherMode"/></param>
/// <param name="paddingMode"><see cref="PaddingMode"/> default is PKCS7</param>
/// <returns>Decrypted byte array</returns>
private static byte[] DESDecrypt(byte[] data, string key, CipherMode cipherMode, string vector = "", PaddingMode paddingMode = PaddingMode.PKCS7)
{
Check.Argument.IsNotEmpty(data, nameof(data));
Check.Argument.IsNotEmpty(key, nameof(key));
Check.Argument.IsEqualLength(key.Length, 24, nameof(key));
byte[] encryptedBytes = data;
byte[] bKey = new byte[24];
Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);
using (MemoryStream Memory = new MemoryStream(encryptedBytes))
{
using (TripleDES des = TripleDES.Create())
{
des.Mode = cipherMode;
des.Padding = paddingMode;
des.Key = bKey;
if (cipherMode == CipherMode.CBC)
{
byte[] bVector = new byte[8];
Array.Copy(Encoding.UTF8.GetBytes(vector.PadRight(bVector.Length)), bVector, bVector.Length);
des.IV = bVector;
}
using (CryptoStream cryptoStream = new CryptoStream(Memory, des.CreateDecryptor(), CryptoStreamMode.Read))
{
try
{
byte[] tmp = new byte[encryptedBytes.Length];
int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length);
byte[] ret = new byte[len];
Array.Copy(tmp, 0, ret, 0, len);
return ret;
}
catch
{
return null;
}
}
}
}
}
呼叫結果
#region DES加密&解密
public static void DES_Encrypt_Decrypt_Test()
{
var srcString = "TEST DES Encrypt Decrypt";
string key = EncryptProvider.CreateDesKey();
string iv = EncryptProvider.CreateDesIv();
var srsDatas = Encoding.UTF8.GetBytes(srcString);
var encrypted = EncryptProvider.DESEncrypt(srsDatas, key, iv);
Console.WriteLine("DES加密結果:" + encrypted);
Console.WriteLine("\r\n");
var decrypted = EncryptProvider.DESDecrypt(encrypted, key, iv);
var decryptedStr = Encoding.UTF8.GetString(decrypted);
Console.WriteLine("DES解密結果:" + decryptedStr);
}
#endregion
AES加密&解密
封裝方法
/// <summary>
/// AES encrypt ( no IV)
/// </summary>
/// <param name="data">Raw data</param>
/// <param name="key">Key, requires 32 bits</param>
/// <returns>Encrypted string</returns>
public static string AESEncrypt(string data, string key)
{
Check.Argument.IsNotEmpty(data, nameof(data));
Check.Argument.IsNotEmpty(key, nameof(key));
Check.Argument.IsEqualLength(key.Length, 32, nameof(key));
using (MemoryStream memory = new MemoryStream())
{
using (Aes aes = Aes.Create())
{
byte[] plainBytes = Encoding.UTF8.GetBytes(data);
byte[] bKey = new byte[32];
Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;
aes.Key = bKey;
using (CryptoStream cryptoStream = new CryptoStream(memory, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
try
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memory.ToArray());
}
catch (Exception ex)
{
return null;
}
}
}
}
}
/// <summary>
/// AES decrypt( no IV)
/// </summary>
/// <param name="data">Encrypted data</param>
/// <param name="key">Key, requires 32 bits</param>
/// <returns>Decrypted string</returns>
public static string AESDecrypt(string data, string key)
{
Check.Argument.IsNotEmpty(data, nameof(data));
Check.Argument.IsNotEmpty(key, nameof(key));
Check.Argument.IsEqualLength(key.Length, 32, nameof(key));
byte[] encryptedBytes = Convert.FromBase64String(data);
byte[] bKey = new byte[32];
Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);
try
{
byte[] decryptedData = null; // decrypted data
using (MemoryStream memory = new MemoryStream(encryptedBytes))
{
using (Aes aes = Aes.Create())
{
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;
aes.Key = bKey;
using (CryptoStream decryptor = new CryptoStream(memory, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
using (MemoryStream tempMemory = new MemoryStream())
{
byte[] buffer = new byte[1024];
Int32 readBytes = 0;
while ((readBytes = decryptor.Read(buffer, 0, buffer.Length)) > 0)
{
tempMemory.Write(buffer, 0, readBytes);
}
decryptedData = tempMemory.ToArray();
return Encoding.UTF8.GetString(decryptedData);
}
}
}
}
}
catch
{
return null;
}
}
呼叫結果
#region AES加密&解密
public static void Aes_Encrypt_Decrypt_Test()
{
var aesKey = EncryptProvider.CreateAesKey();
var key = aesKey.Key;
var srcString = "追逐時光者";
var encrypted = EncryptProvider.AESEncrypt(srcString, key);
Console.WriteLine("AES加密結果:" + encrypted);
Console.WriteLine("\r\n");
var decrypted = EncryptProvider.AESDecrypt(encrypted, key);
Console.WriteLine("AES解密結果:" + decrypted);
}
#endregion
專案原始碼地址
更多專案實用功能和特性歡迎前往專案開源地址檢視?,別忘了給專案一個Star支援?。
優秀專案和框架精選
該專案已收錄到C#/.NET/.NET Core優秀專案和框架精選中,關注優秀專案和框架精選能讓你及時瞭解C#、.NET和.NET Core領域的最新動態和最佳實踐,提高開發工作效率和質量。坑已挖,歡迎大家踴躍提交PR推薦或自薦(讓優秀的專案和框架不被埋沒?
)。
https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md
DotNetGuide技術社群交流群
- DotNetGuide技術社群是一個面向.NET開發者的開源技術社群,旨在為開發者們提供全面的C#/.NET/.NET Core相關學習資料、技術分享和諮詢、專案推薦、招聘資訊和解決問題的平臺。
- 在這個社群中,開發者們可以分享自己的技術文章、專案經驗、遇到的疑難技術問題以及解決方案,並且還有機會結識志同道合的開發者。
- 我們致力於構建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值和成長機會。