【问题标题】:Convert PHP's dot concatenation of a binary part + string part to C#将PHP的二进制部分+字符串部分的点连接转换为C#
【发布时间】:2018-05-09 15:20:37
【问题描述】:

我正在将一段 PHP 代码重写为 C#。此代码用于密码散列。在第一步中,它会生成一个类似“password{salt}”的字符串,然后通过 sha512 哈希算法对其进行哈希处理。之后,一个循环再次对第一个哈希和盐的组合进行哈希 5000 次迭代。

PHP 代码如下所示:

<?php
$password = 'abc';
$salt = 'def';
$salted = $password.'{'.$salt.'}';
$digest = hash('sha512', $salted, true);

for ($i=1; $i<5000; $i++) {
    $digest = hash('sha512', $digest.$salted, true);
}

$encodedPassword = base64_encode($digest);

//$encodedPassword contains the final hash code

我能够让它在没有循环的情况下工作(只需第一次 hash() 调用)。所以主要的散列和base64编码是正确完成的。我发现这部分是我无法用 C# 重写的部分:

$digest.$salted

$digest 似乎是二进制表示,因为 PHP 的 hash() 函数使用“true”作为最后一个参数(参见 PHP hash - manual)。 $salted 是一个字符串。两者都通过 PHP 的 dot / concat 运算符以某种方式神奇地组合在一起。我猜想在将点运算符与非字符串操作数一起使用时,会在后台进行某种从二进制到字符串的标准转换。

这是我目前的代码:

void Main()
{
    string password = "abc";
    string salt = "def";
    string salted = String.Format("{0}{{{1}}}", password, salt);
    byte[] digest = hash(salted);

    for(int i = 1; i < 1; i++) 
    {
        digest = hash(String.Format("{0}{1}", System.Text.Encoding.UTF8.GetString(digest), salted));
    }
    var encodedPassword = System.Convert.ToBase64String(digest);
    //$encodedPassword should contain the final hash code
}

static byte[] hash(string toHash) 
{
    System.Security.Cryptography.SHA512 sha512 = new System.Security.Cryptography.SHA512Managed();
    return sha512.ComputeHash(System.Text.Encoding.UTF8.GetBytes(toHash));
}

如您所见,我尝试使用 System.Text.Encoding.UTF8.GetString() 将哈希字节转换回字符串,然后附加盐,但这不会产生与 PHP 代码相同的输出。

如果有人能在这方面帮助我,我会非常高兴。非常感谢。

【问题讨论】:

  • 你尝试过像 ascii 这样的不同编码吗?你确定二进制哈希是utf8吗?
  • 这确实是编码的问题(就像何塞的回答也指出了)。谢谢你的提示!

标签: c# php


【解决方案1】:

在 PHP 版本中循环 4999 次,而在 C# 版本 0 中。第二个问题是从 hash() 返回的字节根本没有编码。

这应该给您与 PHP 版本相同的结果:

    System.Security.Cryptography.SHA512 sha512 = new System.Security.Cryptography.SHA512Managed();
    var saltedUtf8Bytes = System.Text.Encoding.UTF8.GetBytes(salted);

    for(int i = 1; i < 5000; i++) 
    {
        digest = sha512.ComputeHash(digest.Concat(saltedUtf8Bytes).ToArray());
    }

【讨论】:

  • 非常感谢何塞!使用 .Concat() 进行组合的编码和您的解决方案解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多