加密与解密概述
加密与解密属于数据安全的范畴。在消息传输时,通过对消息进行特殊编码(加密),建立一种安全的交流方式,使得只有发送者所期望的接收者能够理解(解密)。这里我们定义一个场景:发送方,接收方,第三方,发送方要将信息发送给接收方,二第三方想要截取并篡改消息,然后在转发给接收方。要称得上是安全的交流方式,需要满足下面的3个条件:
下面将列出几种常用的技术,看看是否符合上面的3个条件。
散列运算
散列(英语:Hashing)是电脑科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。也译为散列。旧译哈希(误以为是人名而采用了音译)。它也常用作一种资讯安全的实作方法,由一串资料中经过散列算法(Hashing algorithms)计算出来的资料指纹(data fingerPRint),经常用来识别档案与资料是否有被窜改,以保证档案与资料确实是由原创者所提供。如今,散列算法也被用来加密存在数据库中的密码(passWord)字串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码,我公司内的Web管理系统存储的密码字符串就是散列运算的摘要,确实很实用。
散列运算具有以下3个特点:
常见的散列运算如下图所示:
由此可见散列算法只能满足完整性的条件。
对称加密
对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。与公开密钥加密相比,要求双方取得相同的密钥是对称密钥加密的主要缺点之一。
常见的对称加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6。
对称加密流程如下:
由此可见,对称加密可以解决保密的问题,但是要确保第三方没有非法获取到密钥。
非对称加密
非对称加密(asymmetric cryptography),又称为公开密钥加密(英语:public-key cryptography),在这种密码学方法中,需要一对密钥,一是个私人密钥,另一个则是公开密钥。这两个密钥是数学相关,用某用户密钥加密后所得的信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。称公开的密钥为公钥;不公开的密钥为私钥。如果加密密钥是公开的,这用于客户给私钥所有者上传加密的数据,这被称作为公开密钥加密(狭义)。例如,网络银行的客户发给银行网站的账户操作的加密数据。
如果解密密钥是公开的,用私钥加密的信息,可以用公钥对其解密,用于客户验证持有私钥一方发布的数据或文件是完整准确的,接收者由此可知这条信息确实来自于拥有私钥的某人,这被称作数字签名,公钥的形式就是数字证书。例如,从网上下载的安装程序,一般都带有程序制作者的数字签名,可以证明该程序的确是该作者(公司)发布的而不是第三方伪造的且未被篡改过(身份认证/验证)。
常见的公钥加密算法有: RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫尔曼密钥交换协议中的公钥加密算法、椭圆曲线加密算法(英语:Elliptic Curve Cryptography, ECC)。使用最广泛的是RSA算法(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开金钥加密算法,ElGamal是另一种常用的非对称加密算法。
现在假设这种加密方式只使用一组密钥对,根据使用发送方还是接收方的密钥对又可分为加密模式和认证模式。
加密模式下,由消息的接收方发布公钥,持有私钥。基本步骤如下所示:
可以看出非对称加密的加密模式可以解决保密性问题。
认证模式下,由消息的发送方发布公钥,持有私钥。基本步骤如下所示:
可以看出非对称加密的加密模式可以解决认证性问题。
得出结论
上面的技术单一使用无法全部满足完整、保密和认证的3个条件,但是通过组合使用的方式就可以达到目的了。比如说数字签名就是在上面的认证模式加上了散列运算。
加密解密类(苏飞论坛所有)
/// <summary>/// 类说明:Assistant/// 编 码 人:苏飞/// 联系方式:361983679 /// 更新网站: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() { ///默认密码 key = "0123456789"; } private string key; //默认密钥 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 加密字符串 密钥为系统默认 0123456789 /// <summary> /// 加密字符串 密钥为系统默认 /// </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>解密后的结果</returns> static public string SDecryptString(string inputStr, string keyStr) { MySecurity ws = new MySecurity(); return ws.DecryptString(inputStr, keyStr); } /// <summary> /// 解密字符串 密钥为系统默认 /// </summary> /// &l
新闻热点
疑难解答