C#:使用MD5对用户密码加密与解密
C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式。本文总结了通用的算法并结合了自己的一点小经验,分享给大家。
一.使用16位、32位、64位MD5方法对用户名加密
1)16位的MD5加密
/// <summary> /// 16位MD5加密 /// </summary> /// <param name="password"></param> /// <returns></returns> public static string MD5Encrypt16(string password) { var md5 = new MD5CryptoServiceProvider(); string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8); t2 = t2.Replace("-", ""); return t2; }
2)32位的MD5加密
/// <summary> /// 32位MD5加密 /// </summary> /// <param name="password"></param> /// <returns></returns> public static string MD5Encrypt32(string password) { string cl = password; string pwd = ""; MD5 md5 = MD5.Create(); //实例化一个md5对像 // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl)); // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得 for (int i = 0; i < s.Length; i++) { // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 pwd = pwd + s[i].ToString("X"); } return pwd; }
3)64位的MD5加密
public static string MD5Encrypt64(string password) { string cl = password; //string pwd = ""; MD5 md5 = MD5.Create(); //实例化一个md5对像 // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl)); return Convert.ToBase64String(s); }
4)使用MD5为用户密码加密
/// <summary> /// 加密用户密码 /// </summary> /// <param name="password">密码</param> /// <param name="codeLength">加密位数</param> /// <returns>加密密码</returns> public static string md5(string password, int codeLength) { if (!string.IsNullOrEmpty(password)) { // 16位MD5加密(取32位加密的9~25字符) if (codeLength == 16) { return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToLower().Substring(8, 16); } // 32位加密 if (codeLength == 32) { return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToLower(); } } return string.Empty; }
由于MD5是不可逆的,所以加密之后就无法解密,取用户名和密码时候,需要再加密一边用户输入的数据与数据库中已加密的数据进行比对。如果比对结果一致,则可以判定登陆成功!代码如下所示:
/// <summary> /// 登陆 /// </summary> public Model.UserInfo UserLogOn(string USERID, string pwd, out string statusCode) { //假设已经通过用户ID获取到UserInfo的Model对象 Model.UserInfo model = GetModel(USERID); if (model != null) { if (model.PASSWORD == MD5Encrypt64(pwd)) { statusCode = "登陆成功"; } else { statusCode = “密码错误”; } } else { statusCode = "用户不存在!"; model = null; } return model; }
5)通过DESCryptoServiceProvider对象对字符串进行加密解密
/// <summary> /// DES数据加密 /// </summary> /// <param name="targetValue">目标值</param> /// <param name="key">密钥</param> /// <returns>加密值</returns> public static string Encrypt(string targetValue, string key) { if (string.IsNullOrEmpty(targetValue)) { return string.Empty; } var returnValue = new StringBuilder(); var des = new DESCryptoServiceProvider(); byte[] inputByteArray = Encoding.Default.GetBytes(targetValue); // 通过两次哈希密码设置对称算法的初始化向量 des.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5"). Substring(0, 8), "sha1").Substring(0, 8)); // 通过两次哈希密码设置算法的机密密钥 des.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5") .Substring(0, 8), "md5").Substring(0, 8)); var ms = new MemoryStream(); var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); foreach (byte b in ms.ToArray()) { returnValue.AppendFormat("{0:X2}", b); } return returnValue.ToString(); }
此种算法可以通过加密密钥进行解密,解密方法如下:
/// <summary> /// DES数据解密 /// </summary> /// <param name="targetValue"></param> /// <param name="key"></param> /// <returns></returns> public static string Decrypt(string targetValue, string key) { if (string.IsNullOrEmpty(targetValue)) { return string.Empty; } // 定义DES加密对象 var des = new DESCryptoServiceProvider(); int len = targetValue.Length / 2; var inputByteArray = new byte[len]; int x, i; for (x = 0; x < len; x++) { i = Convert.ToInt32(targetValue.Substring(x * 2, 2), 16); inputByteArray[x] = (byte)i; } // 通过两次哈希密码设置对称算法的初始化向量 des.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5"). Substring(0, 8), "sha1").Substring(0, 8)); // 通过两次哈希密码设置算法的机密密钥 des.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5") .Substring(0, 8), "md5").Substring(0, 8)); // 定义内存流 var ms = new MemoryStream(); // 定义加密流 var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); return Encoding.Default.GetString(ms.ToArray()); }
说明:本文章系Healer007原创,署名:小萝卜!部分资料来自互联网,如需转载请注明出处!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript中发布/订阅模式的理解
订阅发布模式的介绍 发布订阅模式,它定义了一种一对多的关系,可以使多个观察者对象对一个主题对象进行监听,当这个主题对象发生改变时,依赖的所有对象都会被通知到。 在生活中我们常常遇到这样一种情况,我们在使用新闻APP看新闻的时候,每个人喜欢的新闻类型各不一样,比如我喜欢NBA,但是我们总不可能一天24小时在手机上一遍又一遍的刷新,我们就会去新闻频道中选择NBA专栏来收藏,当勇士或者湖人有最新消息,就会通知我们去观看。 当然从上面的场景中是一个典型的发布订阅模式,APP的NBA专栏属于发布者,像我一样广大爱好篮球的小伙伴梦就属于订阅者,当一有最新的消息,它们就会发布给我们。 实际用途 1.在jquery中很多地方都有发布订阅的踪迹,例如事件中on和trigger中封装的方法。 2.尤大大的Vue,中子父组件通信使用的emit()和on()方法,使得组件得到解耦,开发更加高效。 如何实现订阅发布模式 1、首先想好谁是发布者(比如上边的APP的NBA专栏就是发布者); 2、然后给发布者添加一个缓存列表,用于存放回调函数来通知订阅者(比如上面的我们球迷爱好者收藏了NBA专栏,相当于向发布者注入了...
- 下一篇
Python找工作并不容易,老表面试了很多企业,总结了些宝贵经验!
一周转眼即逝,面试了7家需要Python程序员的企业,收到了5份Offer,整体来说还不错,感触良多。现在就把这一周的面试经验和大家分享一下,希望为学习Python找工作的小伙伴们提供些许帮助。 1.项目经验 2.项目经验和招聘职位相符 说到底还是看你项目做得是否够多,其余的都只不过是锦上添花。 介绍自己 目前针对Python,人才最为紧缺的当然是人工智能,至于其它的热度较高的当属web开发与爬虫工程师。 二段式询问 不要给自己挖坑 对于自己了解的部分一定要表现出了然于胸,至于不懂的那些知识,只字不提。对于那些自己并不是很熟悉的领域先万不要装逼作死。 我在回答web安全问题时,顺嘴说了SQL注入,面试官说既然提到了SQL注入,那么你讲讲它的原理及解决方法吧!丢脸的是我竟然把XSS跨站注入攻击和SQL注入搞混了,场面也是有点尴尬。所以斟酌你说的每一句话,聪明点的同学还可以引导面试官,让他问出自己想要被问的问题。刚整理了一套2018最新的0基础入门和进阶教程,无私分享,加python学习q-u-n :二二七,四三五,四五零 即可获取,内附:开发工具和安装包,以及系统学习路线图 必问到Red...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群