【问题标题】:migrate from C#.net 2.0 to php so the hash value of the password - how to resolve?从 C#.net 2.0 迁移到 php 所以密码的哈希值 - 如何解决?
【发布时间】:2010-11-04 06:24:33
【问题描述】:

我们之前使用 C#.net 2.0 创建网络应用程序。

使用以下代码对用户密码进行哈希处理并存储在数据库中。

private const string encryptionKey = "AE09F72B007CAAB5";

HMACSHA1 hash = new HMACSHA1();
hash.Key = HexToByte(encryptionKey);
encodedPassword = Convert.ToBase64String(
    hash.ComputeHash(Encoding.Unicode.GetBytes(password)));

现在我们打算迁移到 php。

所以当用户想要返回时,我们会遇到问题。

应该使用什么 php 等效的方法才能使数据库中的哈希值起作用?

例如,编码密码是 pa55w0rd 得到的哈希值为 oK9NOVhpTkxLoLfvh1430SFb5gw=

谢谢。

【问题讨论】:

  • 我想知道从 C# 迁移到 php 背后的原因是什么。此评论有点离题,但我想了解其背后的一些原因。
  • 我们从 C# 开始,因为主要开发人员更熟悉。但是,linux 托管更便宜,因此转向 php。就这些。我可以理解我们没有从正确的决定开始,但我们致力于让它正确。因此采取了行动。

标签: c# php hash migrate hmac


【解决方案1】:

使用 .Net 版本的 PHP (Phalanger) 或使用 .Net 网络服务进行编码/解码不是一种选择?

【讨论】:

  • 感谢 mischa,但我们正在寻求削减成本。因此,如果我们有一个与我们在 c# 中使用的散列函数等效的 php 函数,那就更优雅了。无论如何,谢谢你留下你的答案。现在我知道有长臂猿这样的东西。我以前没听说过。
【解决方案2】:

尝试类似:

<?php
 $key = "AE09F72B007CAAB5";
 echo base64_encode(hash_hmac("sha1", "test", $key, true));
?>

【讨论】:

  • 嗨,不,没有用。我得到了 v1tgPrd6893541ZqrDVr4F1qHw8= 而不是 oK9NOVhpTkxLoLfvh1430SFb5gw=
【解决方案3】:

在 C# 中,哈希的默认格式是 HEX(AE09F72B007CAAB5 是一个十六进制数字)。PHP 默认为 Base64 格式。解决您的问题是将base64字符串转换为php中的十六进制

【讨论】:

  • 嗨,亚历克斯,感谢您的回答。我想问你更多细节,但我得到了我需要的答案。谢谢。
【解决方案4】:

在您的 C# 应用程序中,您以两种不同的方式生成 byte[] 数组,结果略有不同。您的 PHP 脚本需要准确地模拟它们。

hash.Key = HexToByte(encryptionKey)
你传入一个 16 个字符长的字符串,得到一个 8 个字节的数组,就像hash.Key = new byte[]{0xAE, 0x09, 0xF7, 0x2B, 0x00, 0x7C, 0xAA, 0xB5 }; 但是
string password = "pa55w0rd";
byte[] b = Encoding.Unicode.GetBytes(password)
返回一个数组由于 Encoding.Unicode,有 16 个元素,例如 byte[] b = { 0x112, 0x0, 0x97, 0x0, 0x53, 0x0, 0x53, 0x0, 0x119, 0x0, 0x48, 0x0, 0x114, 0x0,0x100, 0x0 }
在您的 php 脚本中,您可以使用 $data = mb_convert_encoding($password, 'UTF16-LE') 将 $password 的编码更改为 utf-16le 以获得类似的结果。 hash_hmac() 不知道任何编码会将字符串视为 16 字节单字节编码字符串,就像 .net 中的 hash.ComputeHash(byte[]) 一样。

<?php
$password = "pa55w0rd";
$key = HexToBytes("AE09F72B007CAAB5"); // 8 bytes, hex

// $to must be 'UTF-16LE' // $from depends on the "source" of $password $data = mb_convert_encoding($password, 'UTF-16LE', 'ASCII');

// I've saved this script as an ascii file -> the string literal is ASCII encoded // therefore php's strlen() returns 8 for $password and 16 for $data // this may differ in your case, e.g. if the contents of $password comes from a // http-request where the data is utf-8 encoded. Adjust the $from parameter for // mb_convert_encoding() accordingly echo 'Debug: |data|=', strlen($data), ' |password|=', strlen($password), "\n";

$h = HexToBytes(hash_hmac('sha1', $data, $key)); echo 'hmac-sha1: ', base64_encode($h);

function HexToBytes($s) { // there has to be a more elegant way... return join('', array_map('chr', array_map('hexdec', str_split($s, 2)))); }

打印
调试:|data|=16 |password|=8
hmac-sha1: oK9NOVhpTkxLoLfvh1430SFb5gw=

【讨论】:

  • 这行得通!谢谢。我本可以就这样离开它。但我想学习并在这方面做得更好。所以帮我解决几个问题。 // http-request,其中数据是 utf-8 编码的。相应地调整 // mb_convert_encoding() 的 $from 参数,目的是构建一个 php 登录页面,所以我想这将是 http 请求?如何判断它是否是 utf-8 编码?如果可能的话如何调整编码?再次感谢您!
  • 顺便说一句,我知道对于 utf8 我需要更改为 $data = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');我的意思是http请求。
  • 简而言之:如果您发送包含 utf-8 编码的登录表单的 html 文档,您可以期望客户端也发送 utf-8 编码的登录数据。很好奇,我在 SO... 上找不到关于该主题的问题?
猜你喜欢
  • 1970-01-01
  • 2011-09-22
  • 2012-02-27
  • 1970-01-01
  • 2018-09-13
  • 2022-11-19
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多