Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不确定如何将C#加密函数移植到PHP_C#_Php_Encryption_Hash - Fatal编程技术网

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

不确定如何将C#加密函数移植到PHP,c#,php,encryption,hash,C#,Php,Encryption,Hash,我在C#中有一个基本的加密功能,用于加密和存储游戏的保存文件,游戏网站使用用户的用户名和密码。最近我意识到,如果用户要更改密码,就会导致他们的存储无法访问,因为它是用他们的旧密码加密的。所以,我试图构建一个PHP函数,在他们更新密码时“重新转换”他们的保存。不幸的是,问题在于C#使用字节数组执行哈希,PHP使用字符串,我不知道如何协调这两者。以下是一般流程: 散列用户名(放入字节数组) 散列密码(放入字节数组) 连接用户名+密码哈希(到两倍长的字节数组中) 获取密钥的哈希结果(返回256位长度

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

  • 散列用户名(放入字节数组)
  • 散列密码(放入字节数组)
  • 连接用户名+密码哈希(到两倍长的字节数组中)
  • 获取密钥的哈希结果(返回256位长度)
  • xor文件逐字节使用密钥获取加密文件
我不知道如何在PHP中实现这一点。我最初尝试使用
unpack('C*',hash('sha256',$thing\u to\u be\u hash,false))
,但这似乎没有产生正确的字节数组。然后我试了一下:

$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
}
$new\u 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();
对于($i=0;$i
不幸的是,这两种方法在任何阶段都不起作用(之前的unpack方法甚至在散列的第一阶段都没有生成正确的字节数组,我也不确定在第二阶段是否正确地将它们放回字符串中)。如果我能得到任何帮助,我将不胜感激。谢谢


编辑:我突然想到
unpack()
不会给我正确的字节数组,因为它实际上是在解码字符串;因此,我想我的主要问题是:首先,“如何将
hash()
返回的十六进制数转换为字节数组?”其次是“如何对这些字节数组进行散列?”(由此推论,“将字节数组转换回六进制数字符串并对其进行散列是否足够?”)

与.NET不同,在.NET中,字符串是Unicode序列编码的,PHP的字符串是哑字节序列——因此本质上,它们已经是字节数组了。因此,在PHP方面,您可以使用字符串完成所有需要的操作,而根本不需要涉及数组,这意味着不需要
unpack

要处理的主要问题是PHP哈希函数默认返回十六进制编码的输出,而不是直接的二进制输出。从一个参数转换到另一个参数非常容易:use,但只将第三个(可选)参数指定为
true
也容易得多

因此,您可以使用以下工具获得所需的哈希值:

// for convenience
function sha256($data) {
    return hash("sha256", $data, true);
}

$new_key = sha256(sha256($username).sha256($newpass));
$old_key = sha256(sha256($username).sha256($oldpass));
然后,此函数将对两个键进行异或运算:

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;
}
函数str\uxor($str1,$str2){
如果(strlen($str1)!=strlen($str2)){
返回false;
}
$len=strlen($str1);
对于($i=0;$i<$len;$i++){
$str1[$i]=$str1[$i]^$str2[$i];
}
返回$str1;
}

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

因此,本质上,在使用
hex2bin
之前,我应该将
hash
的所有输出包装为
hex2bin
?那么,我可以用
$string>访问每个字节吗?它是\u秘密的\u只是\u字节[$I]
?@AlexVanLiew:不需要,在
散列
中有第三个参数自动执行此操作。是的,您可以直接将字符串视为数组。我还在补充答案,我觉得参数返回的字符串像“100010010000100”,这很好。我想这会管用的,让我检查一下。它确实管用。我花了太长的时间来检查,因为我在加载文件和误读哈希过程(两次)时都出现了一些错误。谢谢你的帮助。