.Net中常用的加密解密介绍
2013-05-07 23:45
441 查看
说到加解密,最常见的加密方式:MD5加密
以个人的理解,简单介绍下MD5。MD5的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),本身是不可逆的。其实这也很容易理解,因为MD5值只有128 bits,表示的值范围就在0~2^128这个区间内,而要做MD5的数据是无穷的,那么肯定有某些数据具有相同的MD5值,所以说是不可能恢复原始数据的(不过或许可以得到一个集合,当然那得要让计算机的计算量再翻几倍吧)!
或许有人说已经有王小云破解了MD5,或者某些网站可以进行MD5解密。
首先解释第一个,上面已经说了无数的数据,就有可能会产生相同值。所谓MD5的破解,不是那种由加密后的字符串可以反推回加密前的内容,其实质是加速了杂凑冲撞。例如,字符串a1和a2不同但它们形成的MD5值却相同,王小云的研究成果是在知道a1的情况下,可以通过算法在一定的时间内找到a2,使a1和a2的MD5相同,说白了就是找“碰撞”。或者可以这样理解,原先要找到“碰撞”的复杂度为2^128次方(3.40*10^38,1G是2的30次方,1T是40次方,可以想象128次方是何等的天文数字),经过王小云的算法降低到2^42次方(4.39*10^12),这一数值在当今计算机上,多则几分钟,少则几十秒就能计算完成的。
然后解释第二个,知道了MD5的不可逆,也就容易理解那些网站的解密实则是建立一个大型的数据存储,将加密前和加密后的字符串一一对应(或者一对多?),继而查询出来的。
综上所述,至今为止,MD5都可以称得上是安全的,还有个重要原因就是MD5算法是免费的,所以使用MD5加密不失为一个好方案吧。[以上为个人观点,如有异议,不吝赐教!]
附上.Net中使用MD5的代码:
MD5加密是一种单向加密,用于密码保存来说或许可行。但当一些时候,需要解密获取原信息,就不能采用这种方式了。
为什么要加密、解密?
试想一下,你希望的是只有你和特定的接收者能够理解某条信息,其余人都无法理解此信息,那就是要建立一个暗号,你用暗号加密了信息,接收者用暗号才能解读信息,这个过程就是加密、解密了!
加密通常分为两种方式:对称加密和非对称加密【区别就是密钥(暗号)是否相同】。
1、对称加密:
DES加密:DES使用一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大小。【此种方式可用于加密cookie信息,不至于让cookie完全暴露,安全性是不如AES等方式,但也绰绰有余】
AES加密:AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。
2、非对称加密
非对称加密算法,还有数字签名等,此种方法未接触过,暂不深作讨论。等以后用到了,再来完善。
以个人的理解,简单介绍下MD5。MD5的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),本身是不可逆的。其实这也很容易理解,因为MD5值只有128 bits,表示的值范围就在0~2^128这个区间内,而要做MD5的数据是无穷的,那么肯定有某些数据具有相同的MD5值,所以说是不可能恢复原始数据的(不过或许可以得到一个集合,当然那得要让计算机的计算量再翻几倍吧)!
或许有人说已经有王小云破解了MD5,或者某些网站可以进行MD5解密。
首先解释第一个,上面已经说了无数的数据,就有可能会产生相同值。所谓MD5的破解,不是那种由加密后的字符串可以反推回加密前的内容,其实质是加速了杂凑冲撞。例如,字符串a1和a2不同但它们形成的MD5值却相同,王小云的研究成果是在知道a1的情况下,可以通过算法在一定的时间内找到a2,使a1和a2的MD5相同,说白了就是找“碰撞”。或者可以这样理解,原先要找到“碰撞”的复杂度为2^128次方(3.40*10^38,1G是2的30次方,1T是40次方,可以想象128次方是何等的天文数字),经过王小云的算法降低到2^42次方(4.39*10^12),这一数值在当今计算机上,多则几分钟,少则几十秒就能计算完成的。
然后解释第二个,知道了MD5的不可逆,也就容易理解那些网站的解密实则是建立一个大型的数据存储,将加密前和加密后的字符串一一对应(或者一对多?),继而查询出来的。
综上所述,至今为止,MD5都可以称得上是安全的,还有个重要原因就是MD5算法是免费的,所以使用MD5加密不失为一个好方案吧。[以上为个人观点,如有异议,不吝赐教!]
附上.Net中使用MD5的代码:
/// <summary> /// MD5加密 32位传入密码,返回加密的字符串 /// </summary> /// <param name="pwd"></param> /// <returns></returns> public static string MD5Encrypt(string pwd) { byte[] result = System.Text.Encoding.Default.GetBytes(pwd); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] output = md5.ComputeHash(result); return BitConverter.ToString(output).Replace("-", ""); }
MD5加密是一种单向加密,用于密码保存来说或许可行。但当一些时候,需要解密获取原信息,就不能采用这种方式了。
为什么要加密、解密?
试想一下,你希望的是只有你和特定的接收者能够理解某条信息,其余人都无法理解此信息,那就是要建立一个暗号,你用暗号加密了信息,接收者用暗号才能解读信息,这个过程就是加密、解密了!
加密通常分为两种方式:对称加密和非对称加密【区别就是密钥(暗号)是否相同】。
1、对称加密:
DES加密:DES使用一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大小。【此种方式可用于加密cookie信息,不至于让cookie完全暴露,安全性是不如AES等方式,但也绰绰有余】
/// <summary> /// DEC 加密过程 /// </summary> /// <param name="pToEncrypt">要加密的字符串</param> /// <param name="sKey">密匙</param> /// <returns></returns> public static string Encrypt(string pToEncrypt, string sKey) { try { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); //把字符串放到byte数组中 byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt); des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); //建立加密对象的密钥和偏移量 des.IV = ASCIIEncoding.ASCII.GetBytes(sKey); //原文使用ASCIIEncoding.ASCII方法的GetBytes方法 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); } ret.ToString(); return ret.ToString(); } catch (Exception) { return ""; } } /// <summary> /// DEC 解密过程 /// </summary> /// <param name="pToDecrypt">要解密的字符串</param> /// <param name="sKey">密匙</param> /// <returns></returns> public static string Decrypt(string pToDecrypt, string sKey) { try { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] inputByteArray = new byte[pToDecrypt.Length / 2]; for (int x = 0; x < pToDecrypt.Length / 2; x++) { int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16)); inputByteArray[x] = (byte)i; } des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); //建立加密对象的密钥和偏移量,此值重要,不能修改 des.IV = ASCIIEncoding.ASCII.GetBytes(sKey); MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); StringBuilder ret = new StringBuilder(); //建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象 return System.Text.Encoding.Default.GetString(ms.ToArray()); } catch (Exception ex) { return ex.Message; } }
AES加密:AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。
/// <summary> /// AES对称加密解密类 /// </summary> public class AESHelper { #region 成员变量 /// <summary> /// 密钥(32位,不足在后面补0) /// </summary> private const string _passwd = "ihlih*0037JOHT*)(PIJY*(()JI^)IO%"; /// <summary> /// 运算模式 /// </summary> private static CipherMode _cipherMode = CipherMode.ECB; /// <summary> /// 填充模式 /// </summary> private static PaddingMode _paddingMode = PaddingMode.PKCS7; /// <summary> /// 字符串采用的编码 /// </summary> private static Encoding _encoding = Encoding.UTF8; #endregion #region 辅助方法 /// <summary> /// 获取32byte密钥数据 /// </summary> /// <param name="password">密码</param> /// <returns></returns> private static byte[] GetKeyArray(string password) { if (password == null) { password = string.Empty; } if (password.Length < 32) { password = password.PadRight(32, '0'); } else if (password.Length > 32) { password = password.Substring(0, 32); } return _encoding.GetBytes(password); } /// <summary> /// 将字符数组转换成字符串 /// </summary> /// <param name="inputData"></param> /// <returns></returns> private static string ConvertByteToString(byte[] inputData) { StringBuilder sb = new StringBuilder(inputData.Length * 2); foreach (var b in inputData) { sb.Append(b.ToString("X2")); } return sb.ToString(); } /// <summary> /// 将字符串转换成字符数组 /// </summary> /// <param name="inputString"></param> /// <returns></returns> private static byte[] ConvertStringToByte(string inputString) { if (inputString == null || inputString.Length < 2) { throw new ArgumentException(); } int l = inputString.Length / 2; byte[] result = new byte[l]; for (int i = 0; i < l; ++i) { result[i] = Convert.ToByte(inputString.Substring(2 * i, 2), 16); } return result; } #endregion #region 加密 /// <summary> /// 加密字节数据 /// </summary> /// <param name="inputData">要加密的字节数据</param> /// <param name="password">密码</param> /// <returns></returns> public static byte[] Encrypt(byte[] inputData, string password) { AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.Key = GetKeyArray(password); aes.Mode = _cipherMode; aes.Padding = _paddingMode; ICryptoTransform transform = aes.CreateEncryptor(); byte[] data = transform.TransformFinalBlock(inputData, 0, inputData.Length); aes.Clear(); return data; } /// <summary> /// 加密字符串(加密为16进制字符串) /// </summary> /// <param name="inputString">要加密的字符串</param> /// <param name="password">密码</param> /// <returns></returns> public static string Encrypt(string inputString, string password) { by a15d te[] toEncryptArray = _encoding.GetBytes(inputString); byte[] result = Encrypt(toEncryptArray, password); return ConvertByteToString(result); } /// <summary> /// 字符串加密(加密为16进制字符串) /// </summary> /// <param name="inputString">需要加密的字符串</param> /// <returns>加密后的字符串</returns> public static string EncryptString(string inputString) { return Encrypt(inputString, _passwd); } #endregion #region 解密 /// <summary> /// 解密字节数组 /// </summary> /// <param name="inputData">要解密的字节数据</param> /// <param name="password">密码</param> /// <returns></returns> public static byte[] Decrypt(byte[] inputData, string password) { AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.Key = GetKeyArray(password); aes.Mode = _cipherMode; aes.Padding = _paddingMode; ICryptoTransform transform = aes.CreateDecryptor(); byte[] data = null; try { data = transform.TransformFinalBlock(inputData, 0, inputData.Length); } catch { return null; } aes.Clear(); return data; } /// <summary> /// 解密16进制的字符串为字符串 /// </summary> /// <param name="inputString">要解密的字符串</param> /// <param name="password">密码</param> /// <returns>字符串</returns> public static string Decrypt(string inputString, string password) { byte[] toDecryptArray = ConvertStringToByte(inputString); string decryptString = _encoding.GetString(Decrypt(toDecryptArray, password)); return decryptString; } /// <summary> /// 解密16进制的字符串为字符串 /// </summary> /// <param name="inputString">需要解密的字符串</param> /// <returns>解密后的字符串</returns> public static string DecryptString(string inputString) { return Decrypt(inputString, _passwd); } #endregion }
2、非对称加密
非对称加密算法,还有数字签名等,此种方法未接触过,暂不深作讨论。等以后用到了,再来完善。
相关文章推荐
- .NET 常用加密、解密& 数字签名算法
- 常用加密解密算法【RSA、AES、DES、MD5】介绍和使用
- 常用加密解密算法【RSA、AES、DES、MD5】介绍和使用
- .net常用加密解密方法
- .net常用加密解密方法
- .net常用加密解密方法
- .net常用加密解密方法
- 常用加密解密算法【RSA、AES、DES、MD5】介绍和使用
- .Net加密保护工具分析介绍
- Asp.Net常用加密解密方法
- .NET中加密和解密的实现方法
- .Net使用DES加密,.Net和java分别解密,并正则匹配替换加密密码为明文
- Linux学习笔记之 加密解密介绍,以及运用Openssl创建私有CA
- .Net中的加密解密
- Mysql 常用函数总结(加密解密函数)
- .net 下文件加密和解密
- ★ .net 下文件加密和解密
- JAVASCRIPT加密解密终级指南 本文一共介绍了七种方法: 信息来源:《黑客防线》
- .Net中的加密解密
- Java与.Net环境下RSA加密解密交互不成功的问题解决【续】