一种简单的md5加盐加密的方法(防止彩虹表撞库)

md5加密(或者说摘要算法)大家都很熟悉了 就不解释了

现在很多数据库设计都喜欢用单向加密的方式保存密码,验证时对提交的密码再次加密之后做密文对比

        /// <summary> 使用MD5加密
        /// </summary>
        /// <param name="input">加密字符串</param>
        /// <remarks>2015.08.26</remarks>
        public static Guid ToMD5(string input)
        {
            using (var md5Provider = new MD5CryptoServiceProvider())
            {
                var bytes = Encoding.UTF8.GetBytes(input);
                var hash = md5Provider.ComputeHash(bytes);
                var count = hash.Length;
                hash[0] = (byte)(hash[3] + (hash[3] = hash[0]) * 0); //交换0,3的值
                hash[1] = (byte)(hash[2] + (hash[2] = hash[1]) * 0); //交换1,2的值
                hash[5] = (byte)(hash[4] + (hash[4] = hash[5]) * 0); //交换4,5的值
                hash[7] = (byte)(hash[6] + (hash[6] = hash[7]) * 0); //交换6,7的值
                return new Guid(hash);
            }
        }

  

这种设计最初是防止被暴库之后 黑客可以直接得到用户的密码而设计的,因为是单向加密,所以即便知道加密算法也无法得到用户的实际密码

但是所谓道高一尺魔高一丈, 在彩虹表出现之后, 单纯的md5也不安全了

以下摘自百度百科:

彩虹表是一个用于加密散列函数逆运算的预先计算好的表, 常用于破解加密过的密码散列。一般主流的彩虹表都在100G以上。 查找表常常用于包含有限字符固定长度纯文本密码的加密。这是以空间换时间的典型实践, 在每一次尝试都计算的暴力破解中使用更少的计算能力和更多的储存空间,但却比简单的每个输入一条散列的翻查表使用更少的储存空间和更多的计算性能。使用加盐的KDF函数可以使这种攻击难以实现。

简单的来说就是 攻击者 将简单的密码(123456,111111,888888等)密码事先进行md5加密,得到密文(如123456->e10adc3949ba59abbe56e057f20f883e),然后使用这张表的数据去对比被暴的数据库的密文

这样单纯的md5,很容易就被拿下了

所以后来出现了 2次md5...N次md5, 当然这种也是然并卵......

所以后来出现了加盐加密,

简单来说:比如登录名是blqw ,密码123456 ,则数据库的密文是 md5(123456+blqw),这样可以保证,即使用户的密码是一样的,但密文却不同,这样彩虹表就歇菜了

加盐的方式有很多,一种是 md5(密码+登录名) ,这种方式大部分情况下是可以的

但是登录名修改后,密文也要修改,但是这时候你已经不知道密码的原文是什么了....(虽然一般的登录名是不能修改的,但是产品汪的想法谁知道呢.....)

或者也有人选择多建一个字段用于存放混淆码, 但是依然很麻烦

好了,说了这么多 下面就说说今天的主题,一种比较简单的加盐的方式

        public static Guid ToRandomMD5(string input)
        {
            using (var md5Provider = new MD5CryptoServiceProvider())
            {
                //获取一个256以内的随机数,用于充当 "盐"
                var salt = (byte)Math.Abs(new object().GetHashCode() % 256);
                input += salt;
                var bytes = Encoding.UTF8.GetBytes(input);
                var hash = md5Provider.ComputeHash(bytes);
                hash[0] = salt;
                return new Guid(hash);
            }
        }

        public static bool EqualsRandomMD5(string input, Guid rmd5)
        {
            var arr = rmd5.ToByteArray();
            //将盐取出来
            var salt = arr[0];
            using (var md5Provider = new MD5CryptoServiceProvider())
            {
                input += salt;
                var bytes = Encoding.UTF8.GetBytes(input);
                var hash = md5Provider.ComputeHash(bytes);
                for (int i = 1; i < 16; i++)
                {
                    if (hash[i] != arr[i])
                    {
                        return false;
                    }
                }
                return true;
            }
        }

  

  简单的来说就是把盐放到密文里面 md5 hash完之后得到一个16长度的byte 而byte可以保存0~255的整数 ,所以例子里面,随机的盐就是0~255的数字

然后md5(明文+盐)之后 再将盐保存到 byte[0] 的位置

这样每次hash之后 密文都是不同的 但是依然可以直接密文比较, 这里就是抛砖引玉,觉得255不够的 还可以加一位

当然也可以直接放在1~15的索引上

当然也可以把索引15的byte对15取余后得到0~14然后再放进去....

时间: 2024-10-12 19:28:33

一种简单的md5加盐加密的方法(防止彩虹表撞库)的相关文章

MD5加盐加密

package com.chauvet.utils; import java.security.NoSuchAlgorithmException;import java.util.Random; /*** * MD5 * @author WXW * */public class MD5Util { private final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_."

密码的加盐加密

我们 所 使用密码的加密方式 大多为md5 加密  但是一些不法分子 利用 云计算 分布式计算 可以暴力破解我们的密码 我们通过 加入盐值的方式 加密 密码使得密码 不会被轻易破解 1 //对密码进行加盐加密 2 $password = $this->data['password']; 3 //生成盐值 随机生成几个字符串 4 $altToken = md5(String::randString(10)); 5 //加入盐值 6 $password = md5($password.$altTok

加盐加密salt

加盐加密是一种对系统登录口令的加密方式,它实现的方式是将每一个口令同一个叫做”盐“(salt)的n位随机数相关联. 加盐加密是一种对系统登录口令的加密方式,它实现的方式是将每一个口令同一个叫做”盐“(salt)的n位随机数相关联.无论何时只要口令改变,随机数就改变.随机数以未加密的方式存放在口令文件中,这样每个人都可以读.不再只保存加密过的口令,而是先将口令和随机数连接起来然后一同加密,加密后的结果放在口令文件中. 为什么需要加盐加密? 普通的加密方式不够安全吧,加点盐掺杂在需要加密的字符串中,

关于MD5+salt盐加密

MD5+salt 最近浏览浏览一些帖子时,发现曾经引以为傲的md5加密算法,虽然是无法解密的算法,但是现在可以通过FELHELP(谷歌浏览器插件)或者一些字典可以套出来,.但是当md5+salt值时,套出的几率微乎其微. ---以下参考:微尔雅-的java关于md5+salt盐加密验证 一.陈述一下工作流程: 1.根据已有的密码字符串去生成一个密码+盐字符串,可以将盐的加密字符串也存放在数据库(看需求), 2.验证时将提交的密码字符串进行同样的加密再从数据库中取得已有的盐进行组合密码+盐的字符串

三种简单的html网页自动跳转方法

三种简单的html网页自动跳转方法,可以让你在打开一个html网页时自动跳转到其它的页面. 方法/步骤 <html> <head> <title>正在跳转</title> <meta http-equiv="Content-Language" content="zh-CN"> <meta HTTP-EQUIV="Content-Type" CONTENT="text/ht

MD5 加密 以及 加盐加密

这是MD5加密 - (NSString *)MD5Hash { const char *cStr = [self UTF8String]; unsigned char result[16]; CC_MD5(cStr, strlen(cStr), result); NSString * string= [NSString stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"

md5 加盐

private void button1_Click(object sender, EventArgs e) { string s = GetMd5(textBox1.Text.Trim()); MessageBox.Show(s); } private static string GetMd5(string sDataIn) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bytValue, byt

Java关于md5+salt盐加密验证

一.陈述一下工作流程: 1.根据已有的密码字符串去生成一个密码+盐字符串,可以将盐的加密字符串也存放在数据库(看需求), 2.验证时将提交的密码字符串进行同样的加密再从数据库中取得已有的盐进行组合密码+盐的字符串和已有的进行验证 package com.mi.util; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgori

Android开发之一种简单的异步加载图片方法

首先说明的是,该方法已经被我抛弃了.之前用它,发现加载速度不好.具体没怎么细心的看. 现在我用volley了.拿出来只是给大家批判的. package com.souya.seller.util.ex; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.lang.ref.SoftReference; import java.util.HashMap; impor