2012-01-06 18 views
0

最近、私は暗号化に関するいくつかの研究を行っています。 すべてのことをよりよく理解するために、PHPでより高度なバージョンのXOR Cypherを作成しようとしています。 私はうまく動作するように暗号化機能を持っていますが、復号化機能の出力は、入力されたメッセージとはまったく違っています。PHP:XOR暗号化機能が動作しません。

アルゴリズムの考え方は、最初と最後の文字でXOR演算を実行し、次に2番目と1つではなく最後の文字でXOR演算を実行することです。 その後、最初の2文字と最後の2文字、次に3文字目と4文字目、2文字目と3文字目との間でXOR演算が実行されます。 これは、3,4,5、およびそれ以上の文字のブロックで続きます。私が今持っている

コード:私を助けしようとしているため、事前に

<?php 
function encrypt($message, $key) { 
    $output_text = ''; 

    // Add zeros at the end until the length of the message corresponds with the length of 
the key 
    $message = str_pad($message,strlen($key),0); 

    if((strlen($message) % 2)) { 
     // The lenght of the message is odd, add a zero 
     $message = $message . 0; 
    } 

    // Define the final length of the message 
    $length = strlen($message); 

    // Firstly, take 1 character, then 2, then 3, etc. until you reach half the length of the message 
    for($characters=1; $characters<=($length/2); $characters++) { 
     // Loop from i til half the length of the message 
     for($i=0; $i<=(($length/2)-1); $i += $characters) { 
      // Take the first and last character, the the first two and the last two, etc. 

      // Stop when it crosses half the length 
      if(($i + $characters) >= ($length/2)) break; 

      // firstly, the characters at the beginning 
      $beginning = substr($message, $i, $characters); 
      for($j=0; $j<$characters; $j++) { 
       $position = ($i + 1) + $j; 
       $output_text .= chr(ord($beginning{$j})^ord($key{$position})); 
      } 

      // Then those at the end 
      $ending = substr($message, $length-(($i+1) * $characters), $characters); 
      for($j=0; $j<$characters; $j++) { 
       $position = ($length - (($i + 1)* $characters)) + $j; 
       $output_text .= chr(ord($ending{$j})^ord($key{$position})); 
      } 
     } 
    } 

    return $output_text; 
} 
function decrypt($message, $key) { 
    $output_text = null; 

    // Define the final length of the message 
    $length = strlen($message); 

    // Firstly, take 1 character, then 2, then 3, etc. until you reach half the length of the message 
    for($characters=1; $characters<=($length/2); $characters++) { 

     // Loop from i til half the length of the message 
     for($i=0; $i<=(($length/2)-1); $i += $characters) { 
      // Take the first and last character, the the first two and the last two, etc. 

      // Stop when it crosses half the length 
      if(($i + $characters) >= ($length/2)) break; 

      // firstly, the characters at the beginning 
      $beginning = substr($message, $i, $characters); 
      for($j=0; $j<$characters; $j++) { 
       $position = ($i + 1) + $j; 
       $output_text .= chr(ord($key{$position})^ord($beginning{$j})); 
      } 

      // The those at the end 
      $ending = substr($message, $length-(($i+1) * $characters), $characters); 
      for($j=0; $j<$characters; $j++) { 
       $position = ($length - (($i + 1)* $characters)) + $j; 
       $output_text .= chr(ord($key{$position})^ord($ending{$j})); 
      } 
     } 
    } 

    return $output_text; 
} 

$message = 'sampletextjusttotrythisoutcreatedin2012'; 
$key = '123'; 
$output_text = encrypt($message, $key); 
echo $output_text . '<br /><hr />'; 
echo decrypt($output_text, $key); 

ありがとう!

+0

あなたの「暗号化」アルゴリズムがどのように機能するのかよく分かりませんが、そうではありません。これは、15バイトのクリアテキストを594バイトの暗号テキストに拡張しています。大きなテキストのクリアテキストが含まれています。 – duskwuff

+0

それは私が記事で説明したように動作するはずで、もう一度、実際の使用のためではなく、より良い理解を得るために) – Jeroen

+0

これを置くと、私は暗号化が全く機能しないことを知っていますが、暗号化機能、正しい復号化機能は何でしょうか? – Jeroen

答えて

1

今のところ、文字列を「復号化する」の最も難しい部分は、入力がどれぐらいの長さであったかを調べることです。我々は、追加のパラメータとして、我々はほとんどこのようにそれを解読できることを取る場合:

function decrypt($cipher, $messagelen, $key) { 
    if($messagelen % 2) { $messagelen++; } 
    $x = substr($cipher, -$messagelen + 2); 
    $y = substr($x, 0, strlen($key) - 1)^substr($key, 1); 
    $z = substr($x, strlen($key) - 1); 
    return $y . $z; 
} 

メッセージのほとんどは、暗号文の最後に明確に表示されますので、これは非常に容易になります。おっとっと。その反復において、「暗号化された」唯一の文字は最初の数であり、これは鍵とXORされます。

中間の2文字は、暗号化のoff-by-oneエラーのために回復不能に失われます。これを修正する方法に関する注釈は以下のコメントにあります。

+0

素晴らしい!私はあなたがこれにどのようになったのか疑問に思います、これを説明してもらえますか?暗号化に2つの不足している文字を修正する手助けができたら、私は100ポイントの賞金を投じるでしょう:) – Jeroen

+0

暗号化を修正するには:「長さの半分を越えると停止する」の条件で '> ='を'>'結果を解読するには ' - $ messagelen + 2'(私の関数の3行目)を' $ messagelen'に変更してください。 – duskwuff

+0

ありがとう、それは完璧に動作します!説明に関しては、あなたのコードがどのように動作するかを完全に理解していますが、どうやってそれを知っていますか? – Jeroen

2

メッセージとキーを指定してメッセージを暗号化するためのキーをXORして、少し簡単に始めましょう。暗号化されたメッセージをXORして解読します。

$msg = "The rooster crows at midnight!"; 
$key = "secret key"; 

$cipher_text = simple_xor($msg, $key); 
$plain_text = simple_xor($cipher_text, $key); 

echo "Original msg: $msg\n"; 
echo "Supplied key: $key\n"; 
echo "\n"; 
echo "Cipher Text: " . base64_encode($cipher_text) . "\n"; 
echo " Decrypted: " . $plain_text . "\n"; 

function simple_xor($input, $key) { 

    # Input must be of even length. 
    if (strlen($input) % 2) 
     $input .= '0'; 

    # Keys longer than the input will be truncated. 
    if (strlen($key) > strlen($input)) 
     $key = substr($key, 0, strlen($input)); 

    # Keys shorter than the input will be padded. 
    if (strlen($key) < strlen($input)) 
     $key = str_pad($key, strlen($input), '0', STR_PAD_RIGHT); 

    # Now the key and input are the same length. 
    # Zero is used for any trailing padding required. 

    # Simple XOR'ing, each input byte with each key byte. 
    $result = ''; 
    for ($i = 0; $i < strlen($input); $i++) { 
     $result .= $input{$i}^$key{$i}; 
    } 
    return $result; 
} 

ここでは、XORの本質的な値を見ることができます。 Msg XOR Key = Cと与えられると、C XOR Key = MsgC XOR Msg = Keyとなる。

あなたのアプローチに戻りましょう。より強力な暗号化結果を生成するために、より多くの文字を混在させたいと思われます。これを実行する前に、このような方法でXORを使用する際に、暗号強度をどのように生成するかを考えてください。このプロセスでは、攻撃者が上記のコードを持っていると仮定しますが、$msgまたは$keyではありません。

このアルゴリズムでは、メッセージとキーと同じバイト数の結果が常に生成されるため、攻撃者はメッセージとキーの長さを知ることができます。

最も強いキーは、各バイトが異なるものです。このように、結果にはパターンが含まれません。たとえば、英語のテキストを1つの反復バイトだけを含むキーで暗号化すると、暗号テキストに1バイトが複数回繰り返されていることがわかります。これはおそらく最も一般的な母音であるプレーンテキストの文字 'e'です。鍵が完全にランダムなバイトを含んでいた場合、暗号文に見つかったパターンは、私が平文を識別するのに役立たないでしょう。

「Feet」というメッセージと「abcd」の鍵が強いですか?まあ、それは確かに '0000'のキーを使用するより強力ですが、それはより強くなる可能性があります。攻撃者は、単純なキーを使用していて、小文字だけを使用していると想定している可能性があります。これは、このキーをブルートフォースすることを意味し、攻撃者は26^8の可能なオプションを試す必要があります。現代のコンピュータでは、これは1秒未満で実行できます。より良いキーには、大文字、数字、句読点などの文字が組み込まれます。例えば、$key = chr(27) . chr(6) . 'q.';

このアルゴリズムで考慮するもう1つの興味深い要素は、キーがmsgと同じ長さであることが必要であるということです。これは、大量のテキスト(小説など)を強力に暗号化することは、小説と同じくらい完全にランダムなキーを必要とすることを意味します。ほとんどの主流のアルゴリズムでは、メッセージをブロック単位で暗号化することでこの要件を回避しています。ブロックエンコーディングを実装する方法はいろいろありますが、CBC(Cipher-Block-Chaining)として知られています。

単純なCBCは、プレーンテキストの最初の数バイトを取り出し、それをXORして、暗号テキストの最初の数バイトを生成します。プレーンテキストの次の数バイトは、暗号テキストの最初の数バイトとキーを排他的論理和(XOR)して暗号化されます。このプロセスは、すべてのプレーンテキストが暗号化されるまで繰り返されます。これにより、暗号文の各ブロックが以前のブロックとキーを使用して作成されたチェーンが作成されます。最後の結果を解読するには、暗号テキストを前の暗号テキストブロックとXORしてから、再度そのキーでXORする必要があります。

強力なアルゴリズムには、暗号化されたメッセージが変更されたかどうかを判断できる機能を含む、暗号テキストができるだけランダムであることを保証するための他の機能が組み込まれています。ブロック暗号モードの詳細については、Wikipedia:http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

などがあります。暗号化ページには、暗号化のさまざまな方法や暗号解読プロセスに関する入門情報も豊富に用意されています。 http://en.wikipedia.org/wiki/Cryptography

+0

この広範な答えをお寄せいただきありがとうございました。本当にそのすべてを私に非常によく説明しました! (私はそれを完全に理解する前にそれを数回読まなければならなかったが) – Jeroen

関連する問題