玩轉C#之【Encrypt加密解密】

2022/09/16閱讀時間約 21 分鐘

介紹

這章節純看智商
  • 不可逆加密:原文加密後變成密文,但密文沒辦法解密文回原文
  • 可逆加密:原文加密過後的密文,可以在將密文解密回原文
  • 對稱:表示加解密是否使用同一個key

MD5 不可逆加密

MD5 使用的命名空間是 System.Security.Cryptography
/// <summary>
/// 不可逆加密
/// 1 防止被篡改
/// 2 防止明文儲存
/// 3 防止抵赖,數字簽名
/// </summary>
public class MD5Encrypt
{
#region MD5
/// <summary>
/// MD5加密
/// 使用的UTF8編碼
/// </summary>
/// <param name="source">待加密字串</param>
/// <param name="length">16或32值之一,其他則採用.net默認MD5加密算法</param>
/// <returns>加密后的字串</returns>
public static string Encrypt(string source, int length = 32)//默認參數
{
if (string.IsNullOrEmpty(source)) return string.Empty;
HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
byte[] bytes = Encoding.UTF8.GetBytes(source);//這裡需要區別編碼的
byte[] hashValue = provider.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
switch (length)
{
case 16:
for (int i = 4; i < 12; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
case 32:
for (int i = 0; i < 16; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
default:
for (int i = 0; i < hashValue.Length; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
}
return sb.ToString();
}
#endregion MD5

#region MD5摘要
/// <summary>
/// 獲取檔案的MD5摘要
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string AbstractFile(string fileName)
{
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
return AbstractFile(file);
}
}

/// <summary>
/// 根據stream獲取檔案摘要
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string AbstractFile(Stream stream)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(stream);

StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
#endregion
}
MD5是一種公開的算法,相同的字串可以得到一樣的結果
應用:可以做密碼檢查=>將使用者密碼md5一下,存到資料庫裡,下一次使用者輸入密碼的時候md5一下在做比對
MD5網路上的解密,都是使用樣本比對的方式
密碼複雜一點的方式,加鹽(密碼加上一段文字在做MD5) 或做兩次MD5
以下運用得原理,只有相同文件才能有相同的md5
應用:
  • 防止程式串改:下載VS安裝文件(md5)從官方網站下載,到非官方網站下載只要確認檔案的md5碼有沒有樣就可以
  • 急速秒傳:百度雲 一瞬間就傳完了,第一次上傳,傳完保存MD5,先計算md5--比對-匹配了就不需要上傳了
  • GIT/Svn: md5比對
任何數據MD5後結果都不一樣,到目前為止還沒碰過 2的128次方可能性

DES 對稱可逆加密

應用:數據傳輸
優點:加密速度快
缺點:密鑰的安全是問題
是公開的演算法,即使拿到密文,也推算不了密鑰,也推算不回原文
/// <summary>
/// DES AES Blowfish
///  對稱加密算法的優點是速度快,
///  缺點是密鑰管理不方便,要求共享密鑰。
/// 可逆對稱加密,密鑰長度8
/// </summary>
public class DesEncrypt
{
private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes(Constant.DesKey.Substring(0, 8));
private static byte[] _rgbIV = ASCIIEncoding.ASCII.GetBytes(Constant.DesKey.Insert(0, "w").Substring(0, 8));

/// <summary>
/// DES 加密
/// </summary>
/// <param name="text">需要加密的值</param>
/// <returns>加密后的结果</returns>
public static string Encrypt(string text)
{
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
StreamWriter sWriter = new StreamWriter(crypStream);
sWriter.Write(text);
sWriter.Flush();
crypStream.FlushFinalBlock();
memStream.Flush();
return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
}
}

/// <summary>
/// DES解密
/// </summary>
/// <param name="encryptText"></param>
/// <returns>解密后的结果</returns>
public static string Decrypt(string encryptText)
{
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
byte[] buffer = Convert.FromBase64String(encryptText);

using (MemoryStream memStream = new MemoryStream())
{
CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
crypStream.Write(buffer, 0, buffer.Length);
crypStream.FlushFinalBlock();
return ASCIIEncoding.UTF8.GetString(memStream.ToArray());
}
}
}

RSA 非對稱可逆加密

加密鑰做為私鑰 解密鑰做為公鑰 保證訊息一定來自某個人
加密鑰做為公開 解密鑰做為私有 表示訊息只有我能看的到
加密解密速度不快,安全性好
/// <summary>
/// RSA ECC
/// 可逆非對稱加密
/// 非對稱加密算法的優點是密鑰管理很方便,缺點速度慢。
/// </summary>
public class RsaEncrypt
{
/// <summary>
/// 獲取加密/解密對
/// 给你一個,是無法推算出另外一个的
///
/// Encrypt Decrypt
/// </summary>
/// <returns>Encrypt Decrypt</returns>
public static KeyValuePair<string, string> GetKeyPair()
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string publicKey = RSA.ToXmlString(false);
string privateKey = RSA.ToXmlString(true);
return new KeyValuePair<string, string>(publicKey, privateKey);
}

/// <summary>
/// 加密:内容+加密key
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <returns></returns>
public static string Encrypt(string content, string encryptKey)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(encryptKey);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}

/// <summary>
/// 解密 内容+解密key
/// </summary>
/// <param name="content"></param>
/// <param name="decryptKey">解密key</param>
/// <returns></returns>
public static string Decrypt(string content, string decryptKey)
{
byte[] dataToDecrypt = Convert.FromBase64String(content);
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(decryptKey);
byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
return ByteConverter.GetString(resultBytes);
}


/// <summary>
/// 可以合併在一起的,每次產生一组新的密鑰
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <param name="decryptKey">解密key</param>
/// <returns>加密后结果</returns>
private static string Encrypt(string content, out string publicKey, out string privateKey)
{
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
publicKey = rsaProvider.ToXmlString(false);
privateKey = rsaProvider.ToXmlString(true);

UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
}
關於數字證書SSL之後會專門寫一篇文章跟大家講解

參考資料

本篇已同步發表至個人部落格
https://moushih.com/2022ithome16/
我的鐵人賽文章
為什麼會看到廣告
8會員
39內容數
我是這個部落格的作者,喜歡分享有關投資 💰、軟體開發 💻、占卜 🔮 和虛擬貨幣 🚀 的知識和經驗。
留言0
查看全部
發表第一個留言支持創作者!