可靠地在C#中重现用PHP实现的传统密码散列方法

时间:2017-07-11 09:23:31

标签: c# php hash passwords

我们正在将在Linux上运行的PHP应用程序迁移到我们在C#中实现并在Windows上运行的新单点登录(SSO)基础架构。

作为迁移过程的一部分,我们需要C#SSO基础架构能够以与PHP应用程序完全相同的方式散列密码。

虽然PHP应用程序使用了一个相当合理的密码散列算法,但除了密码和salt 之外,不幸的是,散列的字符串还包含salt值的余弦值(解释为整数)。一个相当不寻常的决定,把它放在中间。

不出所料,事实证明,在PHP和C#中计算大整数的余弦导致结果略有不同。这意味着我们可能无法在新的SSO基础架构中可靠地重新实现传统密码散列算法。

我们考虑的一个解决方案是在AWS Lambda中运行PHP密码散列函数,并从我们的SSO基础架构中查询Lambda。

你能想到其他选择吗?

3 个答案:

答案 0 :(得分:1)

PHP将来自glibc <?php $sql = "SELECT sites_id, sites_nama, sites_alamat, sites_kota_kabupaten, perpanjangan_pagu, sites_tanggal_start, sites_tanggal_finish, perpanjangan_invoice, AVG(perpanjangan_pagu) FROM site"; $result = $conn->query($sql); if ($result->num_rows > 0) { echo "<table> <tr> <th>Site ID</th> <th>Site Name</th> <th>Alamat</th> <th>Kab.Kota</th> <th>Pagu</th> <th>Harga Rata Rata</th> <th>Awal Kontrak</th> <th>Akhir Kontrak</th> <th>Invoice</th> </tr>"; // output data of each row $rows = array(); while ($row = $result->fetch_assoc()) { $rows = $row["AVG(perpanjangan_pagu)"]; echo " <tr> <td>" . $row["sites_id"] . "</td> <td>" . $row["sites_nama"] . "</td> <td>" . $row["sites_alamat"] . "</td> <td>" . $row["sites_kota_kabupaten"] . "</td> <td>" . $row["perpanjangan_pagu"] . "</td> <td>" . $rows . "</td> <td>" . $row["sites_tanggal_start"] . "</td> <td>" . $row["sites_tanggal_finish"] . "</td> <td>" . $row["perpanjangan_invoice"] . "</td> </tr>"; } echo "</table>"; } else { //echo "0 results"; } $conn->close(); ?> 的{​​{1}} cos实现。您可以查看该实现并在应用程序中重新创建它?这可能会变得毛茸茸,因为glibc的数学东西非常复杂。如果在您的应用程序中使用glibc作为依赖项是可以接受的,那么您可以尝试这种方法吗?这就是我开始的地方。

对我来说另一个问题是你实际上也在处理PHP的一些奇数浮点处理,所以并非算法的所有“字符”都来自于所涉及的trig函数。 / em>的

答案 1 :(得分:1)

在你提出的其他问题中

  

使用Visual Studio 2017编译的简单C程序中的C cos(double)函数给出了

c = -0.57977754519881342

虽然你不能完全说出来,但这似乎是你正在寻找的结果(它与Math.Cos的结果肯定不同,不确定它是否正确与PHP有点相同。

所以用VS2017编译一个DLL,然后P /调用它。或者在C运行时库DLL中调用cos(),这肯定会导出所有这些#include <math.h>函数。

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 :(得分:0)

假定盐与每个密码一起存储。您可以使用PHP代码计算该余弦,并将其与密码一起存储。然后,我还将添加一个密码版本号,并将所有这些较早的密码默认为版本1。然后,在您的C#代码中,对于任何新密码,您将实现一个新的哈希算法,并将这些密码哈希存储为密码版本2。对于任何版本1的密码都可以进行身份​​验证,而不必计算余弦,只需使用存储的密码以及密码哈希和salt。

该PHP代码的程序员可能想要做一个聪明的Pepper版本。通过将余弦或胡椒与盐和密码哈希值一起存储,您基本上可以将胡椒变成盐2。因此,执行此操作的另一种无版本方式是在C#哈希代码中使用两种盐。对于新密码,您可以将第二个盐保留为空白或以其他方式分配。对于旧密码,它应该是该余弦,但已经计算出来。