加密與解密概述
加密與解密屬于數(shù)據(jù)安全的范疇。在消息傳輸時,通過對消息進行特殊編碼(加密),建立一種安全的交流方式,使得只有發(fā)送者所期望的接收者能夠理解(解密)。這里我們定義一個場景:發(fā)送方,接收方,第三方,發(fā)送方要將信息發(fā)送給接收方,二第三方想要截取并篡改消息,然后在轉(zhuǎn)發(fā)給接收方。要稱得上是安全的交流方式,需要滿足下面的3個條件:
下面將列出幾種常用的技術(shù),看看是否符合上面的3個條件。
散列運算
散列(英語:Hashing)是電腦科學(xué)中一種對資料的處理方法,通過某種特定的函數(shù)/算法(稱為散列函數(shù)/算法)將要檢索的項與用來檢索的索引(稱為散列,或者散列值)關(guān)聯(lián)起來,生成一種便于搜索的數(shù)據(jù)結(jié)構(gòu)(稱為散列表)。也譯為散列。舊譯哈希(誤以為是人名而采用了音譯)。它也常用作一種資訊安全的實作方法,由一串資料中經(jīng)過散列算法(Hashing algorithms)計算出來的資料指紋(data fingerPRint),經(jīng)常用來識別檔案與資料是否有被竄改,以保證檔案與資料確實是由原創(chuàng)者所提供。如今,散列算法也被用來加密存在數(shù)據(jù)庫中的密碼(passWord)字串,由于散列算法所計算出來的散列值(Hash Value)具有不可逆(無法逆向演算回原本的數(shù)值)的性質(zhì),因此可有效的保護密碼,我公司內(nèi)的Web管理系統(tǒng)存儲的密碼字符串就是散列運算的摘要,確實很實用。
散列運算具有以下3個特點:
常見的散列運算如下圖所示:

由此可見散列算法只能滿足完整性的條件。
對稱加密
對稱密鑰加密(英語:Symmetric-key algorithm)又稱為對稱加密、私鑰加密、共享密鑰加密,是密碼學(xué)中的一類加密算法。這類算法在加密和解密時使用相同的密鑰,或是使用兩個可以簡單地相互推算的密鑰。實務(wù)上,這組密鑰成為在兩個或多個成員間的共同秘密,以便維持專屬的通訊聯(lián)系。與公開密鑰加密相比,要求雙方取得相同的密鑰是對稱密鑰加密的主要缺點之一。
常見的對稱加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6。
對稱加密流程如下:
由此可見,對稱加密可以解決保密的問題,但是要確保第三方?jīng)]有非法獲取到密鑰。
非對稱加密
非對稱加密(asymmetric cryptography),又稱為公開密鑰加密(英語:public-key cryptography),在這種密碼學(xué)方法中,需要一對密鑰,一是個私人密鑰,另一個則是公開密鑰。這兩個密鑰是數(shù)學(xué)相關(guān),用某用戶密鑰加密后所得的信息,只能用該用戶的解密密鑰才能解密。如果知道了其中一個,并不能計算出另外一個。因此如果公開了一對密鑰中的一個,并不會危害到另外一個的秘密性質(zhì)。稱公開的密鑰為公鑰;不公開的密鑰為私鑰。如果加密密鑰是公開的,這用于客戶給私鑰所有者上傳加密的數(shù)據(jù),這被稱作為公開密鑰加密(狹義)。例如,網(wǎng)絡(luò)銀行的客戶發(fā)給銀行網(wǎng)站的賬戶操作的加密數(shù)據(jù)。
如果解密密鑰是公開的,用私鑰加密的信息,可以用公鑰對其解密,用于客戶驗證持有私鑰一方發(fā)布的數(shù)據(jù)或文件是完整準(zhǔn)確的,接收者由此可知這條信息確實來自于擁有私鑰的某人,這被稱作數(shù)字簽名,公鑰的形式就是數(shù)字證書。例如,從網(wǎng)上下載的安裝程序,一般都帶有程序制作者的數(shù)字簽名,可以證明該程序的確是該作者(公司)發(fā)布的而不是第三方偽造的且未被篡改過(身份認(rèn)證/驗證)。
常見的公鑰加密算法有: RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫爾曼密鑰交換協(xié)議中的公鑰加密算法、橢圓曲線加密算法(英語:Elliptic Curve Cryptography, ECC)。使用最廣泛的是RSA算法(由發(fā)明者Rivest、Shmir和Adleman姓氏首字母縮寫而來)是著名的公開金鑰加密算法,ElGamal是另一種常用的非對稱加密算法。
現(xiàn)在假設(shè)這種加密方式只使用一組密鑰對,根據(jù)使用發(fā)送方還是接收方的密鑰對又可分為加密模式和認(rèn)證模式。
加密模式下,由消息的接收方發(fā)布公鑰,持有私鑰。基本步驟如下所示:
可以看出非對稱加密的加密模式可以解決保密性問題。
認(rèn)證模式下,由消息的發(fā)送方發(fā)布公鑰,持有私鑰。基本步驟如下所示:
可以看出非對稱加密的加密模式可以解決認(rèn)證性問題。
得出結(jié)論
上面的技術(shù)單一使用無法全部滿足完整、保密和認(rèn)證的3個條件,但是通過組合使用的方式就可以達到目的了。比如說數(shù)字簽名就是在上面的認(rèn)證模式加上了散列運算。
加密解密類(蘇飛論壇所有)
/// <summary>/// 類說明:Assistant/// 編 碼 人:蘇飛/// 聯(lián)系方式:361983679 /// 更新網(wǎng)站:http://www.sufeinet.com/thread-655-1-1.html/// </summary>using System;using System.Text;using System.Security.Cryptography;using System.IO;using System.Text.RegularExpressions;using System.Collections;namespace DotNet.Utilities{ /// <summary> /// MySecurity(安全類) 的摘要說明。 /// </summary> public class MySecurity { /// <summary> /// 初始化安全類 /// </summary> public MySecurity() { ///默認(rèn)密碼 key = "0123456789"; } private string key; //默認(rèn)密鑰 private byte[] sKey; private byte[] sIV; #region 加密字符串 /// <summary> /// 加密字符串 /// </summary> /// <param name="inputStr">輸入字符串</param> /// <param name="keyStr">密碼,可以為“”</param> /// <returns>輸出加密后字符串</returns> static public string SEncryptString(string inputStr, string keyStr) { MySecurity ws = new MySecurity(); return ws.EncryptString(inputStr, keyStr); } /// <summary> /// 加密字符串 /// </summary> /// <param name="inputStr">輸入字符串</param> /// <param name="keyStr">密碼,可以為“”</param> /// <returns>輸出加密后字符串</returns> public string EncryptString(string inputStr, string keyStr) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); if (keyStr == "") keyStr = key; byte[] inputByteArray = Encoding.Default.GetBytes(inputStr); byte[] keyByteArray = Encoding.Default.GetBytes(keyStr); SHA1 ha = new SHA1Managed(); byte[] hb = ha.ComputeHash(keyByteArray); sKey = new byte[8]; sIV = new byte[8]; for (int i = 0; i < 8; i++) sKey[i] = hb[i]; for (int i = 8; i < 16; i++) sIV[i - 8] = hb[i]; des.Key = sKey; des.IV = sIV; MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); StringBuilder ret = new StringBuilder(); foreach (byte b in ms.ToArray()) { ret.AppendFormat("{0:X2}", b); } cs.Close(); ms.Close(); return ret.ToString(); } #endregion #region 加密字符串 密鑰為系統(tǒng)默認(rèn) 0123456789 /// <summary> /// 加密字符串 密鑰為系統(tǒng)默認(rèn) /// </summary> /// <param name="inputStr">輸入字符串</param> /// <returns>輸出加密后字符串</returns> static public string SEncryptString(string inputStr) { MySecurity ws = new MySecurity(); return ws.EncryptString(inputStr, ""); } #endregion #region 加密文件 /// <summary> /// 加密文件 /// </summary> /// <param name="filePath">輸入文件路徑</param> /// <param name="savePath">加密后輸出文件路徑</param> /// <param name="keyStr">密碼,可以為“”</param> /// <returns></returns> public bool EncryptFile(string filePath, string savePath, string keyStr) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); if (keyStr == "") keyStr = key; FileStream fs = File.OpenRead(filePath); byte[] inputByteArray = new byte[fs.Length]; fs.Read(inputByteArray, 0, (int)fs.Length); fs.Close(); byte[] keyByteArray = Encoding.Default.GetBytes(keyStr); SHA1 ha = new SHA1Managed(); byte[] hb = ha.ComputeHash(keyByteArray); sKey = new byte[8]; sIV = new byte[8]; for (int i = 0; i < 8; i++) sKey[i] = hb[i]; for (int i = 8; i < 16; i++) sIV[i - 8] = hb[i]; des.Key = sKey; des.IV = sIV; MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); fs = File.OpenWrite(savePath); foreach (byte b in ms.ToArray()) { fs.WriteByte(b); } fs.Close(); cs.Close(); ms.Close(); return true; } #endregion #region 解密字符串 /// <summary> /// 解密字符串 /// </summary> /// <param name="inputStr">要解密的字符串</param> /// <param name="keyStr">密鑰</param> /// <returns>解密后的結(jié)果</returns> static public string SDecryptString(string inputStr, string keyStr) { MySecurity ws = new MySecurity(); return ws.DecryptString(inputStr, keyStr); } /// <summary> /// 解密字符串 密鑰為系統(tǒng)默認(rèn) /// </summary> /// &l
新聞熱點
疑難解答