2

CakePHP にレコードを挿入するときに、真に一意のトークンを作成する必要があります。テーブルには何百万もの行が含まれている可能性があるため、ランダムに生成された文字列に基づいているだけではありません。microtime()2 つのレコードがまったく同時に送信される可能性は非常に低いですが、あるため、a も使用したくありません。もちろん、最善の解決策は を使用することString::uuid()ですが、cakephp のドキュメントから

uuid メソッドは、 RFC 4122に従って一意の識別子を生成するために使用されます。uuid は、485fc381-e790-47a3-9794-1337c0a8fe68 の形式の 128 ビット文字列です。

だから、私が理解している限り、それはその生成にケーキのセキュリティソルトを使用していません. そのため、セキュリティ コンポーネントのハッシュ関数 (または認証パスワード関数) によってハッシュすることにしました。これは、一意であると同時に非常に安全である必要があるためです。しかし、それは良い考えではないと言って質問を見つけましたが、php uniqidとmd5の場合です。 MD5 で UUID を使用するのが得策ではないのはなぜですか?

また、セキュリティ コンポーネントによってハッシュされた文字列は、推測するのがはるかに難しいと思います。たとえばString::uuid()、for ループには次のような出力があるためです。

for ($i = 0; $i < 30; $i++) {
    echo String::uuid()."<br>";
}       
die;

// outputs
51f3dcda-c4fc-4141-aaaf-1378654d2d93
51f3dcda-d9b0-4c20-8d03-1378654d2d93
51f3dcda-e7c0-4ddf-b808-1378654d2d93
51f3dcda-f508-4482-852d-1378654d2d93
51f3dcda-01ec-4f24-83b1-1378654d2d93
51f3dcda-1060-49d2-adc0-1378654d2d93
51f3dcda-1da8-4cfe-abe4-1378654d2d93
51f3dcda-2af0-42f7-81a0-1378654d2d93
51f3dcda-3838-4879-b2c9-1378654d2d93
51f3dcda-451c-465a-a644-1378654d2d93
51f3dcda-5264-44b0-a883-1378654d2d93

したがって、文字列の一部は似ていますが、ハッシュ関数を使用する場合、結果はかなり異なります

echo Security::hash('stackoverflow1');
echo "<br>";
echo Security::hash('stackoverflow2');

die;
// outputs
e9a3fcb74b9a03c7a7ab8731053ab9fe5d2fe6bd
b1f95bdbef28db16f8d4f912391c22310ba3c2c2

それで、問題は、結局のところ、Cake で uuid() をハッシュできるかということです。または、真に一意でハッシュ化された(私のセキュリティソルトによると)安全なトークンを取得するための最良の安全な方法は何ですか.

アップデート

安全なトークンとは、推測するのがいかに難しいかということです。UUID は非常にユニークですが、上記の例から、いくつかのレコードには類似性があります。しかし、ハッシュされた結果はそうではありません。

ありがとう !!

4

4 に答える 4

3

UUID の重複について心配する必要はないと思います。

これらの数字を概観すると、誰かが隕石に衝突する年間リスクは 170 億分の 1 の確率であると推定されます[38]。 1 年に数十兆の UUID を作成し、1 つの複製を作成します。言い換えれば、次の 100 年間、毎秒 10 億の UUID を生成した後で初めて、複製が 1 つだけ作成される確率は約 50% になります。別の言い方をすれば、地球上のすべての人が 6 億の UUID を所有している場合、1 つの重複の確率は約 50% になります。

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

String::uuid() を使い続けて、安らかに休んでください :)

于 2014-04-17T18:51:00.600 に答える
1

暗号化の目的に適したランダムな文字列を生成することは、ここでよく答えられました:

PHP での安全な乱数生成

コード サンプルは、文字列 $pr_bits をランダムなバイナリ データで埋めるため、文字は印刷できません。これを URL で使用するには、バイナリ データをいくつかの方法で印刷可能な文字に変換できます。いずれもセキュリティを強化するものではありませんが、URL に対応できるようにします。

  1. バイトを 16 進数に変換します。bin2hex($pr_bits)
  2. バイトを base64 に変換します。base64_encode($pr_bits)
  3. バイトをハッシュします (出力は、セキュリティを強化するためではなく、都合よく 16 進数であるため):string hash ('md5' , $pr_bits)

最後のものを含めるのは、出力が md5 で 16 バイト/128 ビットであることを保証するなど、他の理由で人々がハッシュ関数を使用するのを目にするからです。PHP では、値を HEX に変換するために使用します。

于 2013-07-27T15:36:51.550 に答える
1

UUID は一意です

cakphp にレコードを挿入するときに、本当に一意のトークンを作成する必要があります

それがまさにUUIDです。これは通常、分散システムで衝突 (複数のソースが同期していないデータをデータソースに挿入する) を防ぐために使用されます。

UUID はセキュリティ対策ではありません

ユニークであると同時に非常に安全である必要があります

uuid のハッシュ化がどのようにセキュリティを強化することになっているのかわからない - そうはならない。あいまいさによってセキュリティに依存することは、多かれ少なかれ失敗することが保証されています。

何らかの形式のランダム トークンが必要な場合は、ハッシュ関数を使用します (uuid のハッシュは単にランダム シードのハッシュです)。保証された一意の識別子が必要な場合は、UUID を使用します。それらは同じものではなく、UUID は、ランダムで非順次の「推測不可能な」(または目的が何であれ) 文字列を生成する非常に貧弱なメカニズムです。

于 2013-07-27T15:03:18.523 に答える
1

私は次の解決策を思いついた

マイクロ秒単位の現在の時刻とランダムな文字列のハッシュを連結した結果として文字列を使用する

$timeStr = str_replace("0.", "", microtime());
$timeStr = str_replace(" ", "", $timeStr);
echo Security::hash('random string').'_'.$timeStr;

// 5ffd3b852ccdd448809abb172e19bbb9c01a43a4_796473001379403705

したがって、文字列の最初の部分 (ハッシュ) はトークンの推測不可能性に寄与し、2 番目の部分はその一意性を保証します。

うまくいけば、これは誰かを助けるでしょう。

于 2013-09-17T07:42:41.647 に答える