Reliably reproduce in C# a legacy password hashing method implemented in PHP

倖福魔咒の 提交于 2019-12-10 21:13:34

问题


We are migrating a PHP application that runs on Linux to our new Single Sign-On (SSO) infrastructure implemented in C# and running on Windows.

As part of the migration process, we need our C# SSO infrastructure to be able to hash passwords in the exact same way as the PHP application.

While the PHP application uses a rather reasonable password hashing algorithm, in addition to the password and salt the string that gets hashed unfortunately also contains the cosine of the salt value (interpreted as an integer)... A rather unusual decision, to put it midly.

Unsurprisingly, it turns out that computing the cosine of a large integer in PHP and in C# leads to slightly different results. This means that we probably cannot reliably reimplement the legacy password hashing algorithm in our new SSO infrastructure.

One solution we thought about is running the PHP password hashing function in an AWS Lambda and query that Lambda from our SSO infrastructure.

Can you think of other options?


回答1:


In your other question you write that

C's cos(double) function in a simple C program compiled with Visual Studio 2017 gives

c = -0.57977754519881342

Although you don't say it outright, it appears that this is the result you're looking for (it's certainly different from the result of Math.Cos, not sure if it is bitwise identical to PHP).

So compile a DLL with VS2017 that does that and P/invoke it. Or P/invoke cos() in the C runtime library DLL, which assuredly does export all of these #include <math.h> functions.

c:\Windows\System32>dumpbin /exports msvcr120.dll | find "cos"
       1442  5A1 00081C44 acos
       1443  5A2 00081F2C acosf
       1444  5A3 000821B8 acosh
       1445  5A4 0008227C acoshf
       1446  5A5 0008233C acoshl
       1472  5BF 00083ED4 cacos
       1473  5C0 00084208 cacosf
       1474  5C1 000844BC cacosh
       1475  5C2 00084824 cacoshf
       1476  5C3 00084AF4 cacoshl
       1477  5C4 00084E5C cacosl
       1497  5D8 00086CF4 ccos
       1498  5D9 00086D70 ccosf
       1499  5DA 00086EAC ccosh
       1500  5DB 0008714C ccoshf
       1501  5DC 000873AC ccoshl
       1502  5DD 0008756C ccosl
       1526  5F5 00088640 cos
       1527  5F6 00088BA0 cosf
       1528  5F7 000890A0 cosh
       1529  5F8 00089574 coshf

c:\Windows\System32>dumpbin /exports msvcrt.dll | find "cos"
       1046  415 000372D0 acos
       1047  416 00019BE0 acosf
       1069  42C 000118F0 cos
       1070  42D 00015480 cosf
       1071  42E 000868F0 cosh
       1072  42F 0001ABC0 coshf



回答2:


PHP will be calling the cos implementation from glibc's math.h. You could have a look at that implementation and recreate it in your application? That could get hairy as glibc's math stuff is quite complex. If having glibc as a dependency in your application would be acceptable, you could try that approach? That's where I'd start anyway.

Another concern for me would be that you're actually also dealing with some of PHP's odd floating point handling here too, so not all the "character" of the algorithm is coming from just the trig functions involved.




回答3:


Presumably, the salts are stored along with each password. You could use the PHP code to calculate that cosine, and store that also with the password. I would then also add a password version number and default all those older passwords to be version 1. Then, in your C# code, for any new passwords, you implement a new hashing algorithm, and store those password hashes as passwords version 2. For any version 1 passwords, to authenticate, you do not have to calculate the cosine, you simply use the one stored along with the password hash and the salt.

The programmer of that PHP code was probably wanting to do a clever version of pepper. By storing that cosine, or pepper along with the salt and the password hashes, you basically change that pepper into a salt2. So, another versionless way of doing this would be to use two salts in your C# hashing code. For new passwords you could leave the second salt blank or assign it some other way. For old passwords, it would be that cosine, but it is already calculated.



来源:https://stackoverflow.com/questions/45030449/reliably-reproduce-in-c-sharp-a-legacy-password-hashing-method-implemented-in-ph

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