Problem porting PHP crypt() function to C#

懵懂的女人 提交于 2019-11-29 17:54:38

Alright, so here is the answer:

PHP uses the glibc implementation of the crypt function. (attached: C# implementation)

The reason my old passwords are not matching the hash is because the Linux box my old website (hosted by GoDaddy) sat on had a non-standard hashing algorithm. (Possibly to fix some of the WEIRD stuff done in the algorithm.)

However, I have tested the following implementation against glibc's unit tests and against a windows install of PHP. Both tests were passed 100%.

EDIT
Here is the link: (moved to a Github Gist)

https://gist.github.com/1092558

The crypt() function in PHP uses whatever hash algorithm the underlying operating system provides for encrypting the data - have a look at its documentation. So the first step should be to find out, how the data was encrypted (what hashing algorithm was used). Once you know that, it should be trivial to find the same algorithm for C#.

You can always system() (or whatever the C# static function is called) out to a php command-line script that does the crypt for you.

I would recommend forcing a password change though after successful login. Then you can have a flag that indicates if the user has changed. Once everyone has changed you can dump the php call.

Just reuse the php implementation... Make sure php's crypt libraries are in your system environment path...

You may need to update your interop method to make sure your string marshaling/charset is correct... you can then use the original hashing algorithm.

[DllImport("crypt.dll", CharSet=CharSet.ASCII)]
private static extern string crypt(string password, string salt);

public bool ValidLogin(string username, string password)
{
    string hash = crypt(password, null);
    ...
}

It does not look trivial.

UPDATE: Originally I wrote: "The PHP Crypt function does not look like a standard hash. Why not? Who knows." As pointed out in the comments, the PHP crypt() is the same as used in BSD for passwd crypt. I don't know if that is a dejure standard, but it is defacto standard. So.

I stand by my position that it does not appear to be trivial.

Rather than porting the code, you might consider keeping the old PHP running, and use it strictly for password validation of old passwords. As users change their passwords, use a new hashing algorithm, something a little more "open". You would have to store the hash, as well as the "flavor of hash" for each user.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!