如果用戶(hù) A 要和 B 進(jìn)行數據交換,A 要通過(guò)網(wǎng)絡(luò )發(fā)送一段文字給 B,那如何保證數據在傳輸的過(guò)程中是安全的呢?并且即使被別人截獲,也無(wú)法知道數據的內容,這就用到加密技術(shù)。
對稱(chēng)密碼體制
發(fā)送方用一個(gè)密鑰對數據進(jìn)行加密,接收方使用相同的密鑰進(jìn)行解密。
? 加密和解密 的密鑰相同
? 如何獲取或交換密鑰,保證密鑰的私密性非常重要
? 密鑰量級是參與者的平方級數,數量比較多
? 適合對大量數據進(jìn)行加密,加密解密速度快
? 加解密易于通過(guò)硬件實(shí)現
非對稱(chēng)密碼體制
每個(gè)網(wǎng)絡(luò )參與者都有一對密鑰 - 私鑰和公鑰。用戶(hù) A 的公鑰是公開(kāi)的,任何與 A 通信的人都可以獲取,用來(lái)加密數據后發(fā)送給 A。A 的私鑰只有自己知道,用來(lái)解密數據。
? 公鑰用來(lái)加密,私鑰用來(lái)解密。公私鑰不相同也不相關(guān)
? 公鑰的交換無(wú)需保密
? 密鑰的量級為參與者的數目
? 加解密速度慢,不適合大量數據加密,常用于 對稱(chēng)密碼 協(xié)商共享密鑰
? 加解密操作難以通過(guò)硬件實(shí)現
數字簽名
用戶(hù) A 發(fā)送給 B,B 如何確定數據是用戶(hù) A 發(fā)送的,而不是別人偽造的數據呢?數字簽名可以鑒別消息的發(fā)送者
? 用戶(hù) A 先將要發(fā)送的數據進(jìn)行 MD5 計算生成唯一的 消息摘要 a
? A 用私鑰簽名消息摘要 a
? A 把數據和消息摘要 a 組合起來(lái)發(fā)送給 B
? B 收到后用 A 的公鑰對消息摘要驗簽得到 a
? B 用 MD5 算法對數據部分進(jìn)行計算得到消息摘要 b
? B 對 a 和 b 進(jìn)行比較。如果相同則證明是 A 發(fā)送過(guò)來(lái)的
A 計算數據的消息摘要,并用私鑰進(jìn)行加密的過(guò)程稱(chēng)為 簽名算法。B 用 A 的公鑰解密消息摘要,并與自己計算的消息摘要進(jìn)行對比的過(guò)程稱(chēng)為 驗證算法。
如果直接對數據本身直接計算數字簽名,會(huì )比較耗時(shí)。所以一般做法是先將原數據進(jìn)行 Hash 運算,得到的 Hash 值就叫做“摘要”。
數字證書(shū)
用戶(hù) A 要給用戶(hù) B 發(fā)送數據,如何保證用戶(hù) A 拿到的一定是用戶(hù) B 的公鑰呢?
數字證書(shū)是標志通訊各方身份信息的一串數字,不是數字身份證而是身份認證機構蓋在數字身份證上的一個(gè)章或印。由權威機構-CA(Certificate Authority)發(fā)行的,用來(lái)識別對方的身份。
X.509是一種通用的證書(shū)規范。
常見(jiàn)的數字證書(shū)格式:
? .cer .crt - 用于存放證書(shū),它是二進(jìn)制形式存放的,不含私鑰。
? .pfx .p12 - 存放個(gè)人證書(shū)/私鑰,通常包含保護密碼,2 進(jìn)制方式
從證書(shū)文件獲得證書(shū)對象:
X509Certificate2 cert = new X509Certificate2 (@"c:/myCert.crt" );
// 保護密碼
String password = GetCertPassword();
X509Certificate2 cert = new X509Certificate2 (@"c:/myCert.pfx", password);
從本地證書(shū)容器獲得證書(shū)對象:
private static X509Certificate2 GetCertificateFromStore(string certName)
{
// Get the certificate store for the current user.
X509Store store = new X509Store(StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);
// Place all certificates in an X509Certificate2Collection object.
X509Certificate2Collection certCollection = store.Certificates;
// If using a certificate with a trusted root you do not need to FindByTimeValid, instead:
// currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, true);
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false);
if (signingCert.Count == 0)
return null;
// Return the first certificate in the collection, has the right name and is current.
return signingCert[0];
}
finally
{
store.Close();
}
}
// 驗證證書(shū)有效期
if (cert.NotAfter <= DateTime .Now)
{
throw new ApplicationException (" 用戶(hù)證書(shū)已經(jīng)過(guò)期!" );
}
// 獲取公鑰
RSA publickKey = (RSA)cert.PublicKey.Key;
RSA privateKey = cert.GetRSAPrivateKey();
public class RSAHelper
{
/// RSA加密
///
///公鑰
///
///
public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPublicKey);
byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
return Convert.ToBase64String(provider.Encrypt(bytes, false));
}
///
/// RSA解密
///
///私鑰
///
///
public static string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPrivateKey);
byte[] rgb = Convert.FromBase64String(m_strDecryptString);
byte[] bytes = provider.Decrypt(rgb, false);
return new UnicodeEncoding().GetString(bytes);
}
}
審核編輯:劉清
-
密鑰
+關(guān)注
關(guān)注
1文章
120瀏覽量
19608 -
加密技術(shù)
+關(guān)注
關(guān)注
0文章
142瀏覽量
17302 -
加解密
+關(guān)注
關(guān)注
0文章
17瀏覽量
6494
發(fā)布評論請先 登錄
相關(guān)推薦
評論