3

ここで私が試みたのは、呼び出されるたびに同じ入力を完全に異なる出力に暗号化する関数を作成することです。この関数のベースは xor ですが、文字列内の繰り返しパターンを簡単に見つけられないようにするためです。時間と文字列の部分に基づいてランダムなハッシュを追加し、説明を自己検証しました。

私が求めるのは、文字列にブルート フォースを実行することなく、経験豊富な人に隠されたテキストを明らかにするようなエラーをここで行ったかどうかだけです。(phpには暗号化専用のモジュールがあることは知っていますが、暗号化モジュールが利用できない場合に備えて、これは貧弱なバージョンです。) 2番目:この関数を書き直したり、私のために何かを書いたりすることは求めていません。私が間違ったことをした簡単なガイダンス。セキュリティ違反の可能性の 1 つは、デフォルトでサルサを使用していることです。これは、空の文字列に対してすべてゼロですが、利点は、これが php で利用可能な最長のハッシュであることです。

function crapt($str,$pass,$hmac = false,$meth = 'salsa20') {
   $hash = pack('H*',($hmac===false) ? hash($meth,$pass) : hash_hmac($meth,$pass,$hmac));
   $str = gzdeflate($str,9);
   $tmphash = pack('H*',sha1(sin(microtime(1))));
   $str = $tmphash.((string)$str ^ (string)str_repeat($tmphash,strlen($str)/strlen($tmphash)+1));
   $str .= pack('H*',sha1($str));
   return (string)$str ^ (string)str_repeat($hash,strlen($str)/strlen($hash)+1);
}

function decrapt($str,$pass,$hmac = false,$meth = 'salsa20') {
  $hash = pack('H*',($hmac===false) ? hash($meth,$pass) : hash_hmac($meth,$pass,$hmac));
  $str = (string)$str ^ (string)str_repeat($hash,strlen($str)/strlen($hash)+1);
  $check = substr($str,-20);
  $str = substr($str,0,strlen($str)-20);
  if(pack('H*',sha1($str))!==$check) return false;
  $tmphash = substr($str,0,20);
  $str = substr($str,20);
  return gzinflate((string)$str ^ (string)str_repeat($tmphash,strlen($str)/strlen($tmphash)+1));
}

var_dump(decrapt(crapt('sometext','secretpassword'),'secretpassword'));
4

3 に答える 3

13

自分で発明した暗号には、間違いなく脆弱性があります。スタック オーバーフローにいる私たちがそれを検出できなくても、他の誰かが検出できないわけではありません。暗号化の第 1 のルールは、独自のものを発明しないことです。既存の暗号を使用し、可能であれば、よく知られたテスト済みの実装を使用します。標準ライブラリを絶対に使用できない場合は、TEAなどの既存の暗号を実装するか、選択した言語で既存の実装を見つけてください。

于 2010-12-23T23:08:04.337 に答える
7

アルゴリズムは長さのブロックで動作しますstrlen($hash)==strlen($tmphash)編集:間違っていますが、以下を参照してください。

暗号文では、そのようなブロックの最初のブロックは に等しくなり($tmphash XOR $hash)ます。次のものは、それぞれ に等しい(a_block_of_plaintext XOR $tmphash XOR $hash)です。

暗号文の最初のブロックは、データの鍵です。暗号文の最初のブロックの繰り返しで暗号文を xor するだけで、平文が得られます。パスワードは必要ありません。

私は PHP プログラマーではないので、何か見落としているかもしれませんが、実際の攻撃はこれと大差ありません。

原則として、プロ仕様の暗号化モジュールのみを使用してください。それらが利用できない場合、アプリケーションは安全ではありません。

編集$hash:質問を読み直すことで、$tmphash長さが異なる ことに気づきました。$hashは 512 ビットで、$tmphash160 ビットです。ただし、これは基本的な考え方を変えるものではありません。512 と 160 の最小公倍数は 2560 であるため、ブロックは 2560 ビットごとに同期します。したがって、すべての 2560 ビット ブロックの最初の 160 ビットのみを解読できます。

于 2010-12-24T00:42:13.050 に答える
3

私のphpは素晴らしくなく、私は1学期分の暗号通貨を持っている男なので、決して専門家ではありません。暗号システムの強度を評価する場合、通常、攻撃者がアルゴリズムと実装に完全にアクセスできると想定します。

次の行が表示されます。

 $tmphash = pack('H*',sha1(sin(microtime(1))));

これがあなたの鍵だと思います。私が言ったように、私のPHPはかなり悪いので、間違っている場合は訂正してください。

php sha1関数が40ビットの16進数を返す場合、これによりWEPのキースペースが得られます。前回チェックしたとき、WEPは約3分で割れる可能性があります。これが情報漏えいによるプロトコルに固有の脆弱性に基づいているのか、それともキースペースが非常に小さいためなのか、完全にはわかりません。ただし、16 ^ 40は、暗号化セキュリティに十分な大きさのキースペースではないようです。

さらに、これに基づいて、私が知る必要があるのは、ユーザーがこのリクエストを生成したおおよその時間だけであり、検索する必要のあるキースペースを大幅に減らすことができます。phpのmicrotime()メソッドが実際にエポック以降の現在のマイクロ秒を提供する場合、これにより、キー検索スペースが16 ^ 40(phpのsha1の出力?)から時間枠内のマイクロ秒数に減少します。あなたからこのデータを受け取りました。私は、最も自信を持ったとき(パケットをスニッフィングしたとき)からこのキースペースを通り抜け、ある種のしきい値に達するまでそこから戻るクラッカーを書くことができました。

「私のアルゴリズムは秘密です」というゲームはいつでもプレイできますが、私が知っているほとんどのセキュリティ専門家は、それが非常に有効な議論(またはプレイするのが楽しいゲーム)であるとは本当に感じていません。これらは、あなたのキースペースにのみ対処する非常に基本的な教育を受けた男が出くわした2つの議論にすぎません。

このようなものを自分で実装しないでください。それは悪い考えです。クラス用のおもちゃのプログラムを書いている場合はかっこいいですが、これがあらゆる種類の本番システム用である場合は、実証済みの真の暗号システムを使用することを強くお勧めします。

-ブライアンJ.スティナー-

于 2010-12-24T00:11:03.940 に答える