首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >不确定如何将C#加密函数移植到PHP

不确定如何将C#加密函数移植到PHP
EN

Stack Overflow用户
提问于 2013-10-08 08:34:01
回答 1查看 191关注 0票数 4

我在C#中有一个基本的加密功能,用来加密和存储游戏的文件,它使用用户的用户名和密码来保存游戏的网站。最近,我意识到,如果用户要更改他们的密码,这将导致他们的保存变得不可访问,因为它是用他们的旧密码加密的。因此,我正在尝试构建一个PHP函数,以便在更新密码时“重新转换”他们的保存。不幸的是,问题在于C#使用字节数组来执行散列,而PHP则使用字符串,我不知道如何协调这两者。以下是一般流程:

  • 散列用户名(进入字节数组)
  • 散列密码(进入字节数组)
  • 连接用户名+密码散列(成两倍长的字节数组)
  • 获取键的散列结果(返回256位长度)
  • 异或文件逐字节带密钥以获得加密文件

我不知道如何在PHP中实现这一点。我最初试图使用unpack('C*', hash("sha256", $thing_to_be_hashed, false)),但这似乎没有产生正确的字节数组。然后我试了一下:

代码语言:javascript
代码运行次数:0
运行
复制
$new_key = hash("sha256", hash("sha256", $username, false) . hash("sha256", $newpass, false), false);
$old_key = hash("sha256", hash("sha256", $username, false) . hash("sha256", $oldpass, false), false);

$conversion_key = array();
for($i = 0; $i < strlen($new_key); ++$i) {
    $conversion_key[] = $old_key[$i] ^ $new_key[$i]; 
    // this part with the array is a bit wonky, I know, but it didn't seem like
    // it would have worked anyway since I was xor'ing things like 'f' and '3'
    // instead of bytes like '23' and '57'.
}
$file_contents = file_get_contents("savefile.sav");
for($i = 0; $i < strlen($file_contents); ++$i) {
    $file_contents[$i] = $file_contents[$i] ^ $conversion_key[$i % count($conversion_key)]; // I read somewhere I can access $file_contents like this to get bytes
}

不幸的是,这两种方法在任何阶段都不起作用(以前的unpack方法即使在哈希的第一阶段也没有产生正确的字节数组,我也不确定第二阶段我是否正确地将它们放回了字符串中)。希望我能得到任何帮助。谢谢!

编辑:在我看来,unpack()不会给我正确的字节数组,因为它确实是在解码字符串;所以我想我的主要问题是首先“如何将hash()返回的十六进制转换为字节数组?”第二,“我该如何处理这些字节数组?”(带有推论“是否可以将字节数组转换回十六进制字符串并对这些字符串进行散列?”)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-08 08:47:14

与.NET中的字符串是编码的Unicode序列相比,PHP是由字节组成的哑序列--所以本质上,它们已经是字节数组了。因此,在PHP方面,您可以使用字符串来完成所需的一切,根本不需要涉及数组,这反过来意味着不需要unpack

要处理的主要问题是PHP哈希函数在默认情况下返回十六进制编码,而不是直接的二进制输出。从一种转换到另一种非常容易:使用hex2bin,但也更容易将第三个(可选)参数作为true

这样你就可以得到你需要的哈希:

代码语言:javascript
代码运行次数:0
运行
复制
// for convenience
function sha256($data) {
    return hash("sha256", $data, true);
}

$new_key = sha256(sha256($username).sha256($newpass));
$old_key = sha256(sha256($username).sha256($oldpass));

然后,这个函数将异或这两个键:

代码语言:javascript
代码运行次数:0
运行
复制
function str_xor($str1, $str2) {
    if (strlen($str1) != strlen($str2)) {
        return false;
    }

    $len = strlen($str1);
    for($i=0; $i < $len; $i++) {
        $str1[$i] = $str1[$i] ^ $str2[$i];
    }

    return $str1;
}

因此,您可以使用现有的循环“重新加密”保存的数据从一个密钥到另一个密钥。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19242821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档