2016-03-22 14 views
2

PHPで単純なXOR関数を書いています。それは素晴らしいスタンドアロンで動作しますが、私はクラスに実装するとき、常に "Length Not Match"の例外をスローします。PHP XOR関数が "Length Not Match"を実装しています

XOR機能:

private static function strxor($dataA, $dataB) { 
    if (($dataLen = strlen($dataA)) != strlen($dataB)) { 
     throw new Exception("Length Not Match in strxor"); 
    } 
    $result = ''; 
    for ($i = 0; $i < $dataLen; $i++) { 
     $result .= $dataA[$i]^$dataB[$i]; 
    } 
    return $result; 
} 

私も追加された長さを確認し、変数名に変更して、Encrypt/decrypt with XOR in PHPからコピーされた別のバージョンを試してみました。

private static function xor_this($dataA, $dataB) { 
    if (($dataLen = strlen($dataA)) !== strlen($dataB)) { 
     die("Length Not Match in xor_this"); 
    } 
    $result = ''; 
    for($i=0;$i<$dataLen;) { 
     for($j=0;($j<$dataLen && $i<$dataLen);$j++,$i++) { 
      $result .= $dataA{$i}^$dataB{$j}; 
     } 
    } 
    return $result; 
} 

クラスIは、実装するつもりです:

public static function encrypt($key, $data) { 
    $iv = parent::genSafeRandomBytes(16); 
    $nonce = parent::genSafeRandomBytes(16); 
    $firstBlock = self::xor_this($nonce, $iv); 
    $salt = parent::genSafeRandomBytes(16); 
    $hmac = parent::signText($data, $key); 
    $subkey = parent::genSubKey($key, $salt); 
    $data = self::pkcs7pad($data); 
    $data = str_split($data, 16); 
    $tmp_r = openssl_encrypt($firstBlock, self::CIPHER, $subkey, OPENSSL_RAW_DATA); 
    $result = ''; 
    for ($i = 0; $i < count($data); $i++) { 
     $tmp_n = parent::ivAdd($nonce, $i+1); 
     $tmp_n = self::xor_this($tmp_n, $tmp_r); 
     $tmp_x = openssl_encrypt($tmp_n, self::CIPHER, $subkey, OPENSSL_RAW_DATA); 
     $result .= $tmp_r = self::xor_this($tmp_x, $data[$i]); 
    } 
    return Base62::encode($iv.$nonce.$salt.$hmac.$result); 
} 

私は2つの値が同じ長さを持っていることを確信しています。どうすれば修正できますか?私は実際になぜ、どのようにエラーが発生するのか分かりません。

完全なソース:(動作しない)https://gist.github.com/hartmantam/39857700831591775b1c

+0

奇妙な問題は、それを複製することができませんでした...あなたはhttp://phpfiddle.org/でフィドルを作成してもらえますか? –

+0

あなたはXORの文字列をお互いに直接、右にすることができます知っていますか?あなたはキャラクターごとにキャラクターを行く必要はありません。 '関数strxor($ a、$ b){戻り$ a^$ b; } ' – duskwuff

+0

@JasonFetterly私は本当にphpfiddle.orgの使い方を知らない。だから私はすべてのソース[ここ](https://gist.github.com/hartmantam/39857700831591775b1c)を投稿してください。 – Hartman

答えて

0

デバッグ機能を追加することでは、私は最終的にそれがopenssl_encrypt機能であり、問​​題はXOR機能ではないことがわかりました。 AESのブロックサイズが16で、正しく入力すれば、関数はもう1ブロックを平文に埋め込み、出力を2倍にするので、このエラーが発生します。

解決方法はかなり簡単です。OPENSSL_RAW_DATAOPENSSL_ZERO_PADDINGに変更すると、関数は埋め込みを行いません。この問題は解決しましたが、メッセージを手入力する必要があり、Base64エンコードされた文字列が出力されます。

openssl_encryptを次のように変更し、必要に応じて最初の変数を置き換えます。

openssl_encrypt($firstBlock, self::CIPHER, $subkey, OPENSSL_ZERO_PADDING); 

私が言いたいのすべて:奇妙なデザイン

+0

こんにちは、私は文字列のサイズが暗号化の後に変更されていると思ったが、私のローカルテストサーバーは古いSSLのlibを持っていて、 'pkcs7pad'機能がなかったので、あなたはそれを釘付けにしてうれしい、すみません、私は何の助けでもありませんでした。 –

+0

@JasonFetterly大したことではありません。 – Hartman

関連する問題