C#的MD5加密后的密文跟其他的密文不一样!怎么回事!

时间:2023-01-19 21:22:40

    public string MD5(string strPwd)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] data = System.Text.Encoding.Default.GetBytes(strPwd);//将字符编码为一个字节序列
        byte[] md5data = md5.ComputeHash(data);//计算data字节数组的哈希值
        md5.Clear();
        string str = "";
        for (int i = 0; i < md5data.Length - 1; i++)
        {
            str += md5data[i].ToString("x").PadLeft(2, '0');
        }
        return str;
    }

    public string aaa()
    {
        string pwd1 = MD5("1");
        string pwd2 = pwd1 + "cJfTU2";
        string pwd = MD5(pwd2);
        return pwd1 + "-" + pwd2 + "-" + pwd;
    }
/*
//返回的结果:
c4ca4238a0b923820dcc509a6f7584
-
c4ca4238a0b923820dcc509a6f7584cJfTU2
-
de0003790ddc42ec6957e9e6faffe0

//但是用www.cmd5.com加密1的密文是
c4ca4238a0b923820dcc509a6f75849b
我用其他语言写的MD5密文也同上!
就是C#自带的.结果为什么会不一样!
*/


7 个解决方案

#1


MD5密分两种,一种为16位的,一种为32位的,也就是说加密后的密文长度不一样,如果是16位的加密后一个字符的长度变为16个,所有语言加密后应该是一样的,如果不是那就不叫md5加密了 

#2


引用 1 楼 ajaxtop 的回复:
MD5密分两种,一种为16位的,一种为32位的,也就是说加密后的密文长度不一样,如果是16位的加密后一个字符的长度变为16个,所有语言加密后应该是一样的,如果不是那就不叫md5加密了


你不看代码就在这里说这么多!
我当然是知道MD5加密的密文应该是一样的啊!
所以我才来这里问嘛!

#3



//引用System.Web
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("要加密的字符串", "md5");

#4


晕啊!

你的代码 
i < md5data.Length - 1
 这个对吗?

#5


另外,这应该是应该是一个时刻记起的的警告,你将密码使用md5机制验证时,应该将用户名、用户邮件地址、用户注册时间、开发商名称等等信息全都与strPwd组合在一起,形成长度(往往)超过100个字节的字符串,甚至可以再跟它自己的反转字符串再组合一次,然后才计算MD5散列值。

有些别有用心的人,把一堆什么“1、2、3.....a、b、c”等简单字符的简单(通常是10位以下)的简单组合先计算出md5,然后保存在数据库里,当你给出md5值时他就到数据库里找一下看看有没有匹配的,然后他就忽悠你说他已经可以“解密md5”了。


另外一点,就是首先要对用户设置密码的复杂度本身进行控制。实际上如果密码过度简单,何须费劲去获取程序内部流程中才知道的什么md5值?只要用1、2、11、12之类的简单字母数字组合起来暴利测试几百万次也就试出来了。所以如果密码本身过度简单,玩什么技术都没有用,玩“解密md5”这种欺骗手段也没有必要。

#6


我是怎么发现你的for循环有错误的?其实我只是先去确认你的md5data有没有错误而已。它明明是16位的,但是你的str的长度确实30(应该是32才对)。

这其实说明了一个问题,最好还是依据原始值来设计程序。例如我们的系统中各处,都应该直接使用md5data来进行各种操作,例如保存到数据库中也应该是尽量基于byte[]数组直接保存,而顶多仅仅在某些无关紧要的界面显示时才去临时转换为字符串。

#7


谢谢sp1234是我大意了!

#1


MD5密分两种,一种为16位的,一种为32位的,也就是说加密后的密文长度不一样,如果是16位的加密后一个字符的长度变为16个,所有语言加密后应该是一样的,如果不是那就不叫md5加密了 

#2


引用 1 楼 ajaxtop 的回复:
MD5密分两种,一种为16位的,一种为32位的,也就是说加密后的密文长度不一样,如果是16位的加密后一个字符的长度变为16个,所有语言加密后应该是一样的,如果不是那就不叫md5加密了


你不看代码就在这里说这么多!
我当然是知道MD5加密的密文应该是一样的啊!
所以我才来这里问嘛!

#3



//引用System.Web
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("要加密的字符串", "md5");

#4


晕啊!

你的代码 
i < md5data.Length - 1
 这个对吗?

#5


另外,这应该是应该是一个时刻记起的的警告,你将密码使用md5机制验证时,应该将用户名、用户邮件地址、用户注册时间、开发商名称等等信息全都与strPwd组合在一起,形成长度(往往)超过100个字节的字符串,甚至可以再跟它自己的反转字符串再组合一次,然后才计算MD5散列值。

有些别有用心的人,把一堆什么“1、2、3.....a、b、c”等简单字符的简单(通常是10位以下)的简单组合先计算出md5,然后保存在数据库里,当你给出md5值时他就到数据库里找一下看看有没有匹配的,然后他就忽悠你说他已经可以“解密md5”了。


另外一点,就是首先要对用户设置密码的复杂度本身进行控制。实际上如果密码过度简单,何须费劲去获取程序内部流程中才知道的什么md5值?只要用1、2、11、12之类的简单字母数字组合起来暴利测试几百万次也就试出来了。所以如果密码本身过度简单,玩什么技术都没有用,玩“解密md5”这种欺骗手段也没有必要。

#6


我是怎么发现你的for循环有错误的?其实我只是先去确认你的md5data有没有错误而已。它明明是16位的,但是你的str的长度确实30(应该是32才对)。

这其实说明了一个问题,最好还是依据原始值来设计程序。例如我们的系统中各处,都应该直接使用md5data来进行各种操作,例如保存到数据库中也应该是尽量基于byte[]数组直接保存,而顶多仅仅在某些无关紧要的界面显示时才去临时转换为字符串。

#7


谢谢sp1234是我大意了!