8

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:それは本当に「暗号化」ではありません。難読化という言葉が正しいと思いますが、それは私が行っていることです。ユーザーが簡単に改ざんできないように、重要でないデータを含むコードを渡す必要があります。彼らは、時間制限のあるアクティビティをオフラインで完了し、このコードを介してオンライン スコアボードに時間を送信しています。オフライン アクティビティは、時間 (ミリ秒単位)を難読化します。このコードを受信し、時間を含む文字列に戻すスクリプトを作成する必要があります。

4

9 に答える 9

4

私がそれをどのようにやったか、誰かを助けるかもしれません...

$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);
}
于 2013-01-24T11:08:29.897 に答える
3

ここでいくつかの問題があると思います。それを修正する方法を概説しようとしました。

  • ord(..)バイナリで表現できるように、文字の ASCII 値を取得するために使用する必要があります。たとえば、次のことを試してください。

    printf("%08b ", ord('A')); // outputs "01000001"
    
  • XOR暗号に関するウィキペディアのページで指定されていないため、マルチバイトキーを使用してXOR暗号を行う方法がわかりません。しかし、「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'

于 2011-09-25T21:49:58.560 に答える
1

XOR関連ではなく、コンソール出力とエンコーディングの問題に直面していると思います。xor関数の結果をテキストファイルに出力して、生成された文字のセットを確認してください。生成された文字セットを観察および比較するには、HEXエディターが最良の選択であると思います。

基本的に、テキストを元に戻すには(数字が含まれている場合でも)、同じ関数を使用できます。

var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
于 2011-09-25T21:34:45.353 に答える
1

XOR 操作の結果が印刷可能な文字を生成するという保証はありません。あなたがこれを行っている理由についてより良いアイデアを提供していただければ、おそらく代わりに何か賢明なことを行うように指示することができます.

于 2011-09-25T21:16:13.963 に答える
1

あなたが得ているという事実に基づいて、xor_this( xor_this('123') ) = '123'これは単に出力の問題であると推測します. ブラウザにデータを送信すると、ブラウザはそれを HTML でレンダリングする必要があるもの (最初の半ダースの ASCII 文字など) として認識します。ページのソースを見て、実際に何があるかを確認してください。さらに良いことに、出力を繰り返し処理し、ord各位置の値をエコーし​​ます。

于 2011-09-25T21:58:22.087 に答える
0
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
    $outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}

注:それはおそらくいくつかの奇妙なキャラクターを作成します...

于 2011-09-25T21:51:21.217 に答える
0

これを試して:

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

2 つのオペランドのいずれかが整数の場合、PHP はもう一方を整数にキャストし、XOR 演算を行って数値結果を取得します。

または、これを使用することもできます:

$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
于 2011-09-25T21:45:09.467 に答える
-3

すべての賢明な提案にもかかわらず、私はこの問題をもっと簡単な方法で解決しました。

鍵変えました!キーを次のようなものに変更すると、次のようになります。

$key = 'ISINUS0478331006';

...印刷可能な文字の難読化された出力を生成します。

于 2011-09-29T13:41:40.670 に答える