【问题标题】:Xor encryption in PHPPHP中的异或加密
【发布时间】:2011-11-24 19:23:30
【问题描述】:

我是 Xor 加密的新手,我在使用以下代码时遇到了一些问题:

function xor_this($string) {

// Let's define our key here
 $key = ('magic_key');

 // Our plaintext/ciphertext
 $text =$string;

 // Our output text
 $outText = '';

 // Iterate through each character
 for($i=0;$i<strlen($text);)
 {
     for($j=0;$j<strlen($key);$j++,$i++)
     {
         $outText .= $text{$i} ^ $key{$j};
         //echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
     }
 }  
 return $outText;
}

当我运行它时,它适用于普通字符串,例如“dog”,但它仅部分适用于包含数字的字符串,例如“12345”。

为了演示……

xor_this('dog') = 'UYV'

xor_this('123') = ''

注意到xor_this( xor_this('123') ) = '123' 也很有趣,正如我所期望的那样。我很确定问题出在我对按位运算符的模糊理解中,或者可能是 PHP 处理包含数字的字符串的方式。我敢打赌那里有聪明的人确切地知道这里出了什么问题。谢谢。

编辑#1:这不是真正的“加密”。我想混淆是正确的术语,这就是我正在做的事情。我需要从用户那里传递一个包含不重要数据的代码,而他们不能轻易地篡改它。他们正在离线完成一项定时活动,并通过此代码将他们的时间提交到在线记分牌。离线活动将混淆他们的时间(以毫秒为单位)。我需要编写一个脚本来接收此代码并将其转回包含他们时间的字符串。

【问题讨论】:

  • 我希望你不打算将它用于家庭作业以外的任何事情:P
  • 尝试将$string 转换为类似$string = (string)$string 的字符串。另外,请注意“加密”对于异或事物来说是一个相当强的词,所以不要在生产环境中使用它。
  • 你工作太辛苦了。 PHP 很乐意对字符串的每个字符进行异或运算,并将结果作为另一个字符串给出。你不需要一个循环来自己做,只需做$str1 ^ $str2。但当心!结果字符串将与最短字符串一样长! (包括空字符串!)所以先填充字符串,或者分块做。
  • 如果您只使用 php 已经拥有的一些内置编码/解码功能,您可能会更安全并且工作量更少。例如 mcrypt 函数。 phpdoc 页面有示例。

标签: php bitwise-operators xor bitwise-xor


【解决方案1】:

我是怎么做到的,可能会对某人有所帮助......

$msg = 'say hi!';
$key = 'whatever_123';

// print, and make unprintable chars available for a link or alike.
// using $_GET, php will urldecode it, if it was passed urlencoded
print "obfuscated, ready for url: " . urlencode(obfuscate($msg, $key)) . "\n";
print "deObfuscated: " . obfuscate(obfuscate($msg, $key), $key);


function obfuscate($msg, $key) {
    if (empty($key)) return $msg;
    return $msg ^ str_pad('', strlen($msg), $key);
}

【讨论】:

    【解决方案2】:

    我认为您可能在这里遇到了一些问题,我已尝试概述我认为您可以如何解决它:

    • 您需要使用ord(..) 来获取字符的ASCII 值,以便您可以将其表示为二进制。例如,尝试以下操作:

      printf("%08b ", ord('A')); // outputs "01000001"
      
    • 我不确定您如何使用多字节密钥进行 XOR 密码,因为 the wikipedia page on XOR cipher 没有指定。但我假设对于像“123”这样的给定键,您的键开始“左对齐”并延伸到文本的长度,如下所示:

      function xor_this($text) {
          $key = '123';
          $i = 0;
          $encrypted = '';
          foreach (str_split($text) as $char) {
              $encrypted .= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
          }
          return $encrypted;
      }
      print xor_this('hello'); // outputs "YW_]]"
      

      加密'hello' 宽度密钥'12312'。

    【讨论】:

      【解决方案3】:

      不能保证 XOR 运算的结果会产生可打印的字符。如果您让我们更好地了解您这样做的原因,我们可能会为您指出一些明智的做法。

      【讨论】:

      • 我希望我的编辑能够阐明我想要做什么。我实际上不需要加密任何东西。我的任务只是解密我收到的任何内容,并且我想确保我的函数能够正确处理整数,因为这正是我将收到的。
      【解决方案4】:

      我相信您面临的是控制台输出和编码问题,而不是与 XOR 相关的问题。 尝试在文本文件中输出 xor 函数的结果并查看一组生成的字符。我相信 HEX 编辑器将是观察和比较生成的字符集的最佳选择。

      基本上要恢复文本(偶数在),您可以使用相同的功能:

      var $textToObfuscate = "Some Text 12345";
      var $obfuscatedText = $xor_this($textToObfuscate);
      var $restoredText = $xor_this($obfuscatedText);
      

      【讨论】:

        【解决方案5】:

        基于您收到xor_this( xor_this('123') ) = '123' 的事实,我愿意猜测这只是一个输出问题。您正在向浏览器发送数据,浏览器将其识别为应该以 HTML 呈现的内容(例如,前半打 ASCII 字符)。尝试查看页面源代码以了解实际存在的内容。更好的是,遍历输出并回显每个位置的值的ord。

        【讨论】:

          【解决方案6】:

          使用此代码,它可以完美运行

          function scramble($inv) {
            $key=342244;  // scramble key
            $invarr=str_split($inv);
            for($index=0;$index<=strlen($inv)-1;$index++) {
              srand($key);
              $var=rand(0,255);
              $res=$res.(chr(ord($var)) ^ chr(ord($invarr[$index])));
              $key++;
            }
            return($res);
          }
          

          【讨论】:

            【解决方案7】:

            试试这个:

            $outText .= (string)$text{$i} ^ (string)$key{$j};
            

            如果两个操作数之一是整数,PHP 将另一个转换为整数并对它们进行异或运算以获得数值结果。

            或者,你可以使用这个:

            $outText .= chr(ord($text{$i}) ^ ord($key{$j}));
            

            【讨论】:

              【解决方案8】:
              // Iterate through each character
              for($i=0; $i<strlen($text); $i++)
              {
                  $outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
              }
              

              注意:它可能会创建一些奇怪的字符...

              【讨论】:

                【解决方案9】:

                尽管有所有明智的建议,我还是以更简单的方式解决了这个问题:

                我换了钥匙!事实证明,通过将密钥更改为更像这样的东西:

                $key = 'ISINUS0478331006';

                ...它将生成可打印字符的混淆输出。

                【讨论】:

                • 你知道为什么它现在可以工作了吗?如果没有,你怎么知道下次什么时候出现问题?
                • 可能对您来说是一个解决方案,但对于遇到此问题的其他人来说,它不是解决方案,因为它只适用于您的危险角色。
                猜你喜欢
                • 1970-01-01
                • 2020-08-12
                • 1970-01-01
                • 1970-01-01
                • 2021-05-16
                • 1970-01-01
                • 1970-01-01
                • 2014-01-01
                • 2011-01-03
                相关资源
                最近更新 更多