C#實(shí)現(xiàn)加密與解密詳解
一、Hash加密,使用HashAlgorithm哈希算法類的派生類(MD5、SHA1等)
特點(diǎn):只能加密,不可逆??蓪?duì)目標(biāo)信息生成一段特定長(zhǎng)度唯一的Hash值。
HashAlgorithm派生類包括:
- KeyedHashAlgorithm: 顯示所有加密哈希算法實(shí)現(xiàn)均必須從中派生的抽象類。
- MD5: 表示 MD5 哈希算法的所有實(shí)現(xiàn)均從中繼承的抽象類。
————MD5Crypto?Service?Provider:使用加密服務(wù)提供程序 (CSP) 提供的實(shí)現(xiàn),計(jì)算輸入數(shù)據(jù)的 MD5 哈希值。 - RIPEMD160: 表示 MD160 哈希算法的所有實(shí)現(xiàn)均從中繼承的抽象類。
- SHA1: 計(jì)算輸入數(shù)據(jù)的 SHA1 哈希值。
————SHA1Crypto?Service?Provider:使用加密服務(wù)提供程序 (CSP) 提供的實(shí)現(xiàn),計(jì)算輸入數(shù)據(jù)的 SHA1 哈希值。 - SHA256: 計(jì)算輸入數(shù)據(jù)的 SHA256 哈希值。
- SHA384: 計(jì)算輸入數(shù)據(jù)的 SHA384 哈希值。
- SHA512: 計(jì)算輸入數(shù)據(jù)的 SHA512 哈希值。
1、使用抽象類HashAlgorithm
//明文密碼由字符串轉(zhuǎn)換為byte數(shù)組
byte[] clearBytes =Encoding.Default.GetBytes("123");
//由明文的byte數(shù)組計(jì)算出MD5密文byte數(shù)組
byte[] hashedBytes = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(clearBytes);
//把byte數(shù)組轉(zhuǎn)換為字符串后返回,BitConverter用于將基礎(chǔ)數(shù)據(jù)類型與字節(jié)數(shù)組相互轉(zhuǎn)換
string result = BitConverter.ToString(hashedBytes).Replace("-", "");
Console.Write(result);2、使用抽象類MD5
byte[] clearBytes = Encoding.Default.GetBytes("123");
byte[] hashedBytes = MD5.Create().ComputeHash(clearBytes);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hashedBytes.Length; i++)
{
sBuilder.Append(hashedBytes[i].ToString("x2"));
}
string result = sBuilder.ToString();
Console.Write(result);3、使用MD5CryptoServiceProvider類
byte[] clearBytes = Encoding.Default.GetBytes("123");
byte[] hashedBytes = new MD5CryptoServiceProvider().ComputeHash(clearBytes);
string result = "";
for (int i = 0; i < hashedBytes.Length; i++)
result += hashedBytes[i].ToString("X").PadLeft(2, '0');
Console.Write(result);4、Web使用的Hash加密:FormsAuthentication類
FormAuthentication.HashPasswordForStoringInConfigFile(str,"MD5")//或者“SHA1”
5、文件哈希計(jì)算
- MD5是一個(gè)將任意長(zhǎng)度的數(shù)據(jù)字符串轉(zhuǎn)化成短的固定長(zhǎng)度的值的單向操作。任意兩個(gè)字符串不應(yīng)有相同的散列值(即,有“很大可能”是不一樣的,并且要人為地創(chuàng)造出來兩個(gè)散列值相同的字符串應(yīng)該是困難的)。
- 因此MD5經(jīng)常用于校驗(yàn)字符串或者文件,因?yàn)槿绻募腗D5不一樣,說明文件內(nèi)容也是不一樣的,即經(jīng)過修改的,如果發(fā)現(xiàn)下載的文件和給的md5值不一樣,就需要慎重使用。
- MD5文件校驗(yàn)用途非常多,例如:游戲patch包的校驗(yàn),病毒文件確認(rèn),app提審校驗(yàn)等等,只要需要確認(rèn)某一個(gè)文件的唯一性和正確性,都會(huì)使用md5作為校驗(yàn)。
輸入文件路徑,就可以得到對(duì)應(yīng)的哈希值,這個(gè)哈希值是對(duì)文件本身內(nèi)容包括文件名字有關(guān),跟文件存放的路徑和運(yùn)行平臺(tái),設(shè)備無關(guān)。
string GetFileHash(string path)
{
var hash = MD5.Create();//SHA1.Create();
var stream = new FileStream(path, FileMode.Open);
byte[] hashByte = hash.ComputeHash(stream);
stream.Close();
return BitConverter.ToString(hashByte).Replace("-", "");
}二、對(duì)稱加密:使用SymmetricAlgorithm對(duì)稱算法類的派生類(Aes、DES等)
特點(diǎn):指加密和解密使用相同密鑰的加密算法。
對(duì)稱加密算法的優(yōu)點(diǎn)在于加解密的高速度和使用長(zhǎng)密鑰時(shí)的難破解性。
SymmetricAlgorithm派生類包括:
- Aes:表示高級(jí)加密標(biāo)準(zhǔn) (AES) 的所有實(shí)現(xiàn)都必須從中繼承的抽象基類。
————Aes?Crypto?Service?Provider:使用高級(jí)加密標(biāo)準(zhǔn) (AES) 算法的加密應(yīng)用程序編程接口 (CAPI) 實(shí)現(xiàn)來執(zhí)行對(duì)稱加密和解密。 - DES:表示所有 DES 實(shí)現(xiàn)都必須從中派生的數(shù)據(jù)加密標(biāo)準(zhǔn) (DES) 算法的基類。
————DESCrypto?Service?Provider:定義訪問數(shù)據(jù)加密標(biāo)準(zhǔn) (DES) 算法的加密服務(wù)提供程序 (CSP) 版本的包裝對(duì)象。 - RC2:表示 RC2 算法的所有實(shí)現(xiàn)都必須從中派生的基類。
- Rijndael:表示 Rijndael 對(duì)稱加密算法的所有實(shí)現(xiàn)必須從其繼承的基類。
- TripleDES:表示三重?cái)?shù)據(jù)加密標(biāo)準(zhǔn)算法的基類
public static string strKey = "abcdefgh";//注意:這里的密鑰sKey必須能轉(zhuǎn)為8個(gè)byte,即輸入密鑰為8半角個(gè)字符或者4個(gè)全角字符或者4個(gè)漢字的字符串
public static string strIV = "ijklmnop";
// 加密
public static string Encrypt(string _strQ)
{
byte[] buffer = Encoding.UTF8.GetBytes(_strQ);
MemoryStream ms = new MemoryStream();
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
CryptoStream encStream = new CryptoStream(ms, des.CreateEncryptor(Encoding.UTF8.GetBytes(strKey), Encoding.UTF8.GetBytes(strIV)), CryptoStreamMode.Write);
encStream.Write(buffer, 0, buffer.Length);
encStream.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
// 解密
public static string Decrypt(string _strQ)
{
byte[] buffer = Convert.FromBase64String(_strQ);
MemoryStream ms = new MemoryStream();
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
CryptoStream encStream = new CryptoStream(ms, des.CreateDecryptor(Encoding.UTF8.GetBytes(strKey), Encoding.UTF8.GetBytes(strIV)), CryptoStreamMode.Write);
encStream.Write(buffer, 0, buffer.Length);
encStream.FlushFinalBlock();
return Encoding.UTF8.GetString(ms.ToArray());
}三、非對(duì)稱加密:使用AsymmetricAlgorithm非對(duì)稱算法類的派生類(DSA、RSA等)
特點(diǎn):指加密和解密使用不同密鑰的加密算法,也稱為公私鑰加密。公鑰是可以公開用來加密,私匙嚴(yán)格由接受方保密用于加密。
非對(duì)稱加密的缺點(diǎn)是加解密速度要遠(yuǎn)遠(yuǎn)慢于對(duì)稱加密。
AsymmetricAlgorithm派生類包括:
- DSA:表示數(shù)字簽名算法(DSA)的所有實(shí)現(xiàn)都必須從中繼承的抽象基類。
————DSACryptoServiceProvider:使用加密服務(wù)提供程序 (CSP) 提供的 DSA算法的實(shí)現(xiàn)執(zhí)行不對(duì)稱加密和解密。 - ECDiffie?Hellman:
- ECDsa:
- RSA:表示 RSA 算法的所有實(shí)現(xiàn)均從中繼承的基類。
————RSACrypto?Service?Provider:使用加密服務(wù)提供程序 (CSP) 提供的 RSA 算法的實(shí)現(xiàn)執(zhí)行不對(duì)稱加密和解密。
///
/// 獲取加密所使用的key,RSA算法是一種非對(duì)稱密碼算法,所謂非對(duì)稱,就是指該算法需要一對(duì)密鑰,使用其中一個(gè)加密,則需要用另一個(gè)才能解密。
///
public static void GetKey()
{
string PublicKey = string.Empty;
string PrivateKey = string.Empty;
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
PublicKey = rSACryptoServiceProvider.ToXmlString(false);
// 獲取公匙,用于加密
PrivateKey = rSACryptoServiceProvider.ToXmlString(true);
// 獲取公匙和私匙,用于解密
//Console.WriteLine("PublicKey is {0}", PublicKey); // 輸出公匙
//Console.WriteLine("PrivateKey is {0}", PrivateKey); // 輸出密匙
//密匙中含有公匙,公匙是根據(jù)密匙進(jìn)行計(jì)算得來的。
using (StreamWriter streamWriter = new StreamWriter("PublicKey.xml"))
{
streamWriter.Write(rSACryptoServiceProvider.ToXmlString(false));// 將公匙保存到運(yùn)行目錄下的PublicKey
}
using (StreamWriter streamWriter = new StreamWriter("PrivateKey.xml"))
{
streamWriter.Write(rSACryptoServiceProvider.ToXmlString(true)); // 將公匙&私匙保存到運(yùn)行目錄下的PrivateKey
}
}
///
/// 加密
///
private static string Encryption(string str)
{
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
using (StreamReader streamReader = new StreamReader("PublicKey.xml")) // 讀取運(yùn)行目錄下的PublicKey.xml
{
rSACryptoServiceProvider.FromXmlString(streamReader.ReadToEnd()); // 將公匙載入進(jìn)RSA實(shí)例中
}
byte[] buffer = Encoding.UTF8.GetBytes(str); // 將明文轉(zhuǎn)換為byte[]
// 加密后的數(shù)據(jù)就是一個(gè)byte[] 數(shù)組,可以以 文件的形式保存 或 別的形式(網(wǎng)上很多教程,使用Base64進(jìn)行編碼化保存)
byte[] EncryptBuffer = rSACryptoServiceProvider.Encrypt(buffer, false); // 進(jìn)行加密
return Convert.ToBase64String(EncryptBuffer); // 如果使用base64進(jìn)行明文化,在解密時(shí) 需要再次將base64 轉(zhuǎn)換為byte[]
}
///
/// 解密
///
private static string Decrypt(string strEncryptBase64)
{
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
using (StreamReader streamReader = new StreamReader("PrivateKey.xml")) // 讀取運(yùn)行目錄下的PrivateKey.xml
{
rSACryptoServiceProvider.FromXmlString(streamReader.ReadToEnd()); // 將私匙載入進(jìn)RSA實(shí)例中
}
byte[] buffer = Convert.FromBase64String(strEncryptBase64);
// 解密后得到一個(gè)byte[] 數(shù)組
byte[] DecryptBuffer = rSACryptoServiceProvider.Decrypt(buffer, false); // 進(jìn)行解密
string str = Encoding.UTF8.GetString(DecryptBuffer); // 將byte[]轉(zhuǎn)換為明文
return str;
}到此這篇關(guān)于C#加密與解密的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#對(duì)接阿里云IOT平臺(tái)進(jìn)行設(shè)備開發(fā)
這篇文章介紹了C#對(duì)接阿里云IOT平臺(tái)進(jìn)行設(shè)備開發(fā),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01
C#執(zhí)行存儲(chǔ)過程并將結(jié)果填充到GridView的方法
這篇文章主要介紹了C#執(zhí)行存儲(chǔ)過程并將結(jié)果填充到GridView的方法,結(jié)合實(shí)例形式分析了C#存儲(chǔ)過程操作及GridView控件相關(guān)操作技巧,需要的朋友可以參考下2017-02-02
C#?WPF?ListBox?動(dòng)態(tài)顯示圖片功能
這篇文章主要介紹了C#?WPF?ListBox?動(dòng)態(tài)顯示圖片,處理過程分為前臺(tái)代碼和后臺(tái)代碼,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
C# TextBox多行文本框的字?jǐn)?shù)限制問題
最近在使用C# TextBox多行文本框的時(shí)候,發(fā)現(xiàn)了其對(duì)字?jǐn)?shù)限制的一點(diǎn)問題,所以總結(jié)下在使用C# TextBox多行文本框要注意的的字?jǐn)?shù)限制問題,現(xiàn)在分享給大家,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12

