PHP 是最好的语言! 那怎么兼容这个原来的.net 的历史遗留问题

2015-06-02 16:37:47 +08:00
 skyworker

手上有个系统,是.net写的。这个.net系统在加密用户密码时候,没有用salt,而是在MD5的基础上,进行了16进制转换和位偏移,并且用户的历史密码也是用这种方式来保存:

public static string Encrypt(string pwd)
        {
            StringBuilder returnValue = new StringBuilder();
            var data = Encoding.Unicode.GetBytes(pwd);
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

            var result = md5.ComputeHash(data);

            foreach (var t in result)
            {
                returnValue.Append(t.ToString("X", CultureInfo.CurrentCulture).PadLeft(2, '0'));
            }

            return returnValue.ToString();
        }

那么作为最好的语言,PHP怎么才能写一个类似的密码验证函数?嗯,主要是用在登录的时候,匹配用户密码是否正确。微软那一套东西很久就不看了,实在搞不通.net那帮家伙们,直接用salt不久解决了的问题,非要弄一段自以为了不起的“变种”MD5加密。

嗯,问题来了,有木有熟悉PHP和.net的高手帮我用PHP实现一下?

3946 次点击
所在节点    PHP
18 条回复
Livid
2015-06-02 16:39:17 +08:00
MD5CryptoServiceProvider 的源代码你有吗?
breestealth
2015-06-02 16:40:11 +08:00
难道PHP保存密码的标准姿势不应该是自带的password_hash和password_verify么?
skyworker
2015-06-02 16:42:28 +08:00
@Livid MD5CryptoServiceProvider 应该是.net默认的

@breestealth 这是为了兼容老系统。老系统是用这段代码加密用户password的,php系统只能针对老系统,做一个外围。所以php只能兼容老的.net系统的加密方式
Septembers
2015-06-02 16:44:25 +08:00
$password = md5(mb_convert_encoding($pwd, 'UTF-16LE'));
see https://stackoverflow.com/a/16538976
skyworker
2015-06-02 16:49:30 +08:00
@Septembers 我靠,差不多解决了。PHP产生的password只是在大小写上不一样,应该能用参数解决。

再说一遍,PHP是最好的语言
Septembers
2015-06-02 16:52:06 +08:00
@skyworker 善用Google(我不是PHPer
fangjinmin
2015-06-02 17:43:51 +08:00
你给的这个代码取的就是MD5码的,并没有位移什么的, 只不过, .net的这段代码不保证是小写。
webflier
2015-06-02 17:55:08 +08:00
MD5CryptoServiceProvider 的代码在Microsoft .NET Reference Source里有。请移步github。
另外,也可参考mono的实现
Athrob
2015-06-02 18:26:28 +08:00
其实找个会C#的一看就懂了, 被这标题吸引到了...
jeriwu
2015-06-02 18:27:37 +08:00
楼主是不是想要这个函数 ord ?
klmun
2015-06-02 20:48:18 +08:00
作为一枚.net狗告诉你,这个就是普通的md5。
skyworker
2015-06-02 21:30:44 +08:00
@klmun 我觉得,var result = md5.ComputeHash(data); 应该才是是用.net内置的MD5 hash默认算法获取的哈希密码。

然后后来的那一坨迭代,我觉得是这个函数的作者在自作聪明,对默认的哈希密码再做个小处理。 不知道我猜的对不对。
caoyue
2015-06-02 22:36:20 +08:00
你们想多了,这就是 md5 的 C# 标准实现
注意是 md5(unicode),楼主之前 md5 结果不对可能是没有做编码转换
caoyue
2015-06-02 23:20:17 +08:00
@caoyue
忘了说了,C# 所谓的 Encoding.Unicode 实际上是 UTF-16

php 不会,上面的 Encrypt 函数等价于 Python 的
hashlib.md5(u'123456'.encode('utf-16le')).hexdigest()
hjc4869
2015-06-02 23:38:07 +08:00
看了下标题。。。怎么我最近是在.NET里处理PHP里的历史遗留问题…难道楼主和我的时间线是反的……
Hyperion
2015-06-03 00:17:34 +08:00
这个其实不能叫历史遗留问题, 这个应该叫语言和库的差异问题..
clowwindy
2015-06-03 17:35:01 +08:00
问题不在 .Net 和 PHP,在于你并不理解字符串和编码 =。=
caizixian
2015-06-06 13:45:45 +08:00
@clowwindy 对头

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/195568

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX