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.

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

报告相同问题?

悬赏问题

  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效