C#對稱加密與非對稱加密實例
本文實例講述了C#對稱加密與非對稱加密的原理與實現方法,分享給大家供大家參考。具體分析如下:
一、對稱加密(Symmetric Cryptography)
對稱加密是最快速、最簡單的一種加密方式,加密(encryption)與解密(decryption)用的是同樣的密鑰(secret key)。對稱加密有很多種算法,由于它效率很高,所以被廣泛使用在很多加密協議的核心當中。
對稱加密通常使用的是相對較小的密鑰,一般小于256 bit。因為密鑰越大,加密越強,但加密與解密的過程越慢。如果你只用1 bit來做這個密鑰,那黑客們可以先試著用0來解密,不行的話就再用1解;但如果你的密鑰有1 MB大,黑客們可能永遠也無法破解,但加密和解密的過程要花費很長的時間。密鑰的大小既要照顧到安全性,也要照顧到效率,是一個trade-off。
2000年10月2日,美國國家標準與技術研究所(NIST--American National Institute of Standards and Technology)選擇了Rijndael算法作為新的高級加密標準(AES--Advanced Encryption Standard)。.NET中包含了Rijndael算法,類名叫RijndaelManaged,下面舉個例子。
加密過程:
private string myPassword = "OpenSesame";
private byte[] cipherText;
private byte[] salt = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0 };
private void mnuSymmetricEncryption_Click(object sender, RoutedEventArgs e)
{
var key = new Rfc2898DeriveBytes(myPassword, salt);
// Encrypt the data.
var algorithm = new RijndaelManaged();
algorithm.Key = key.GetBytes(16);
algorithm.IV = key.GetBytes(16);
var sourceBytes = new System.Text.UnicodeEncoding().GetBytes(myData);
using (var sourceStream = new MemoryStream(sourceBytes))
using (var destinationStream = new MemoryStream())
using (var crypto = new CryptoStream(sourceStream, algorithm.CreateEncryptor(), CryptoStreamMode.Read))
{
moveBytes(crypto, destinationStream);
cipherText = destinationStream.ToArray();
}
MessageBox.Show(String.Format("Data:{0}{1}Encrypted and Encoded:{2}", myData, Environment.NewLine, Convert.ToBase64String(cipherText)));
}
private void moveBytes(Stream source, Stream dest)
{
byte[] bytes = new byte[2048];
var count = source.Read(bytes, 0, bytes.Length);
while (0 != count)
{
dest.Write(bytes, 0, count);
count = source.Read(bytes, 0, bytes.Length);
}
}
解密過程:
{
if (cipherText == null)
{
MessageBox.Show("Encrypt Data First!");
return;
}
var key = new Rfc2898DeriveBytes(myPassword, salt);
// Try to decrypt, thus showing it can be round-tripped.
var algorithm = new RijndaelManaged();
algorithm.Key = key.GetBytes(16);
algorithm.IV = key.GetBytes(16);
using (var sourceStream = new MemoryStream(cipherText))
using (var destinationStream = new MemoryStream())
using (var crypto = new CryptoStream(sourceStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read))
{
moveBytes(crypto, destinationStream);
var decryptedBytes = destinationStream.ToArray();
var decryptedMessage = new UnicodeEncoding().GetString(
decryptedBytes);
MessageBox.Show(decryptedMessage);
}
}
對稱加密的一大缺點是密鑰的管理與分配,換句話說,如何把密鑰發(fā)送到需要解密你的消息的人的手里是一個問題。在發(fā)送密鑰的過程中,密鑰有很大的風險會被黑客們攔截?,F實中通常的做法是將對稱加密的密鑰進行非對稱加密,然后傳送給需要它的人。
二、非對稱加密(Asymmetric Cryptography)
非對稱加密為數據的加密與解密提供了一個非常安全的方法,它使用了一對密鑰,公鑰(public key)和私鑰(private key)。私鑰只能由一方安全保管,不能外泄,而公鑰則可以發(fā)給任何請求它的人。非對稱加密使用這對密鑰中的一個進行加密,而解密則需要另一個密鑰。比如,你向銀行請求公鑰,銀行將公鑰發(fā)給你,你使用公鑰對消息加密,那么只有私鑰的持有人--銀行才能對你的消息解密。與對稱加密不同的是,銀行不需要將私鑰通過網絡發(fā)送出去,因此安全性大大提高。
目前最常用的非對稱加密算法是RSA算法,是Rivest, Shamir, 和Adleman于1978年發(fā)明,他們那時都是在MIT。.NET中也有RSA算法,請看下面的例子:
加密過程:
private void mnuAsymmetricEncryption_Click(object sender, RoutedEventArgs e)
{
var rsa = 1;
// Encrypt the data.
var cspParms = new CspParameters(rsa);
cspParms.Flags = CspProviderFlags.UseMachineKeyStore;
cspParms.KeyContainerName = "My Keys";
var algorithm = new RSACryptoServiceProvider(cspParms);
var sourceBytes = new UnicodeEncoding().GetBytes(myData);
rsaCipherText = algorithm.Encrypt(sourceBytes, true);
MessageBox.Show(String.Format("Data: {0}{1}Encrypted and Encoded: {2}",
myData, Environment.NewLine,
Convert.ToBase64String(rsaCipherText)));
}
解密過程:
{
if(rsaCipherText==null)
{
MessageBox.Show("Encrypt First!");
return;
}
var rsa = 1;
// decrypt the data.
var cspParms = new CspParameters(rsa);
cspParms.Flags = CspProviderFlags.UseMachineKeyStore;
cspParms.KeyContainerName = "My Keys";
var algorithm = new RSACryptoServiceProvider(cspParms);
var unencrypted = algorithm.Decrypt(rsaCipherText, true);
MessageBox.Show(new UnicodeEncoding().GetString(unencrypted));
}
雖然非對稱加密很安全,但是和對稱加密比起來,它非常的慢,所以我們還是要用對稱加密來傳送消息,但對稱加密所使用的密鑰我們可以通過非對稱加密的方式發(fā)送出去。為了解釋這個過程,請看下面的例子:
① Alice需要在銀行的網站做一筆交易,她的瀏覽器首先生成了一個隨機數作為對稱密鑰。
② Alice的瀏覽器向銀行的網站請求公鑰。
③ 銀行將公鑰發(fā)送給Alice。
④ Alice的瀏覽器使用銀行的公鑰將自己的對稱密鑰加密。
⑤ Alice的瀏覽器將加密后的對稱密鑰發(fā)送給銀行。
⑥ 銀行使用私鑰解密得到Alice瀏覽器的對稱密鑰。
⑦ Alice與銀行可以使用對稱密鑰來對溝通的內容進行加密與解密了。
三、總結
① 對稱加密加密與解密使用的是同樣的密鑰,所以速度快,但由于需要將密鑰在網絡傳輸,所以安全性不高。
② 非對稱加密使用了一對密鑰,公鑰與私鑰,所以安全性高,但加密與解密速度慢。
③ 解決的辦法是將對稱加密的密鑰使用非對稱加密的公鑰進行加密,然后發(fā)送出去,接收方使用私鑰進行解密得到對稱加密的密鑰,然后雙方可以使用對稱加密來進行溝通。
希望本文所述對大家的C#程序設計有所幫助。
相關文章
C# 繪制統(tǒng)計圖大全(柱狀圖, 折線圖, 扇形圖)
本篇文章介紹了C# 繪制統(tǒng)計圖大全,其中包括狀圖, 折線圖, 扇形圖,有需要的同學可以了解一下。2016-11-11C#通過創(chuàng)建Windows服務啟動程序的方法詳解
這篇文章主要介紹了C#通過創(chuàng)建Windows服務啟動程序的方法,較為詳細的分析了C#創(chuàng)建Windows服務應用程序的步驟與相關注意事項,需要的朋友可以參考下2016-06-06Unity報錯InvalidOperationException: out of sync的解決
今天在做個東西,發(fā)現報錯,特此來記錄一下,本文介紹了Unity報錯InvalidOperationException: out of sync的解決,感興趣的可以了解一下2021-05-05C#中數組、ArrayList、List、Dictionary的用法與區(qū)別淺析(存取數據)
在工作中經常遇到C#數組、ArrayList、List、Dictionary存取數據,但是該選擇哪種類型進行存儲數據呢?很迷茫,今天小編抽空給大家整理下這方面的內容,需要的朋友參考下吧2017-02-02C#基礎知識之GetType與typeof的區(qū)別小結
在比較對象時,需要了解他們的類型,才能決定他們的值是否能比較。所有的類都從System.Object中繼承了GetType()方法,常常與typeo()運算符一起使用。這篇文章主要給大家介紹了關于C#基礎知識之GetType與typeof區(qū)別的相關資料,需要的朋友可以參考下2021-06-06