doubao6464 2013-10-08 08:34 采纳率: 100%
浏览 41
已采纳

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

I have a basic encryption function in C# that I use to encrypt and store save files for a game, which uses a user's username and password for the game's website. Recently I realized that if a user was to change their password, it would cause their save to become inaccessible, since it's encrypted with their old password. So, I'm trying to build a PHP function to "reconvert" their save when they update their password. Unfortunately, the problem comes in that C# uses byte arrays to perform hashing, and PHP uses strings, and I'm not sure how to reconcile the two. Here's the general process:

  • hash username (into byte array)
  • hash password (into byte array)
  • concatenate username + password hashes (into twice-as-long byte array)
  • hash result to get key (which is back to the 256-bit length)
  • xor file byte-by-byte with key to get encrypted file

I'm not sure how to accomplish this in PHP. I was originally trying to use unpack('C*', hash("sha256", $thing_to_be_hashed, false)) but this didn't seem to yield the correct byte arrays. Then I tried this:

$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
}

Neither method works, unfortunately, at any stage (the previous unpack method didn't produce correct byte arrays for even the first stage of hashing, nor am I sure I was putting them back into a string correctly for the second stage). Would appreciate any help I can get. Thanks!

EDIT: It occurred to me unpack() wouldn't be giving me the correct byte arrays because it's literally decoding the strings; so I guess my main question is firstly "how would I convert the hexits returned by hash() to byte arrays?" and secondly "how would I go about hashing those byte arrays?" (with corollary "would converting the byte arrays back to strings of hexits and hashing those be sufficient?")

  • 写回答

1条回答 默认 最新

  • doz22551 2013-10-08 08:47
    关注

    In contrast to .NET where strings are encoded Unicode sequences, PHP's strings are dumb sequences of bytes -- so in essence, they already are byte arrays. So on the PHP side you can do all you need with strings and there is no need to involve arrays at all, which in turn means unpack is not required.

    The main thing to deal with is that PHP hash functions return hex-encoded instead of straight binary output by default. It's very easy to convert from one to the other: use hex2bin, but it's also much easier to just give the third (optional) argument as true.

    So you can get the hashes you need with:

    // for convenience
    function sha256($data) {
        return hash("sha256", $data, true);
    }
    
    $new_key = sha256(sha256($username).sha256($newpass));
    $old_key = sha256(sha256($username).sha256($oldpass));
    

    This function will then XOR the two keys:

    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;
    }
    

    So you can then use your existing loop to "re-encrypt" the saved data from one key to the other.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog