web-dev-qa-db-ja.com

md5よりも短いphp暗号?

さまざまな愚かな理由から、外部サーバーに投稿する特定のフォーム変数の最大長は12文字です。

Md5でその値を隠したかったのですが、明らかに12文字では機能しません。すでに作成されているPHP関数を使用して、12文字以下になる暗号はありますか?

ここでは、暗号のセキュリティと整合性はそれほど重要ではありません。私の最後の手段は、各文字をASCII値でxだけ上下に移動する関数を作成することです。したがって、目標は暗号化の専門家からそれを隠すことではなく、プレーンテキストで投稿しないことです。そのため、それを見ている非技術者はそれが何であるかを知りません。

アドバイスありがとうございます。

20
tiredofcoding

これは この回答 への追加です。

答えは、md5の32文字表現から最初の12文字を取得することを提案しています。したがって、20文字の情報が失われます。これにより、wayより多くの衝突が発生する可能性があります。

16文字表現(生の形式)の最初の12文字を使用することにより、情報の損失を減らすことができます。

substr(md5($string, true), 0, 12);

これにより、データの75%が維持されますが、32文字形式を使用するとデータの37.5%しか維持されません。

16
NikiC

おそらくこれは、衝突のリスクを高めることなく、URLで渡すことができる12文字の文字列を生成するのに役立ちます

substr(base_convert(md5($string), 16,32), 0, 12);
16
Codebutcher

多分crc32()を試してみませんか?

9
Alex Howansky

ハッシュが必要な場合でも、md5ハッシュの最初の12文字を使用できます。

substr(md5($yourString), 0, 12);
8
Colin Hebert

すべての答えは、一部のデータを失うことを示唆しています(衝突の可能性が高い)が、ベース変換を使用する方が良いアプローチのようです。ここで説明されているように http://proger.i-forge.net/Short_MD5/OMF

ランダムな文字列を生成してデータベースに挿入し、保存する前にまだ存在していないかどうかを確認することもできます。これにより、ハッシュを短くして、衝突が発生しないようにすることができます。

4
takeshin

暗号化された値が送信されるスクリプトをユーザーが制御していると想定する必要があるため、この提案を広める必要があります。

また、多くのフォームフィールドを作成できると想定する必要がありますが、それぞれの長さが12文字を超えることはできません。

その場合、単に複数のフォームフィールドを作成し、md5文字列を複数の非表示フィールドに分散させることはできませんか?

Md5文字列を8つのチャンクに分割し、各チャンクを非表示のフォームフィールドに送信してから、もう一方の端でそれらを結合することができます。

ちょっとした考え...

3
Adam

OPは2方向関数を探していたので、これはおそらく役に立たないでしょうが、md5よりも短いハッシュを探している人には役立つかもしれません。これが私のニーズのために思いついたものです(base64_encode関数を強調表示してくれた https://rolandeckert.com/notes/md5 に感謝します)。 md5ハッシュをbase(64)としてエンコードし、望ましくないbase(64)文字を削除します。母音+および/を削除しているので、有効ベースを64から52に減らします。

C文字の後にbase(b)でエンコードされたハッシュを切り捨てると、b ^ cの一意のハッシュが可能になることに注意してください。これは衝突を回避するのに十分堅牢ですか?ハッシュするアイテム(k)の数によって異なります。衝突の確率はおおよそ(k * k)/(b ^ c)/ 2であるため、以下の関数を使用してk = 100万のアイテムをハッシュし、ベースb = 52のエンコーディングをc = 12文字の後に切り捨てた場合衝突の確率7億5000万分の1未満です。 c = 12文字の後に16進エンコード(b = 16)ハッシュを切り捨てるのと比較してください。衝突の確率はおよそ500分の1です! 16進エンコードされたハッシュを切り捨てることにはノーと言ってください。 :)

私は手足に出て、以下の関数(長さ12)は1000万アイテム(衝突の確率750万分の1未満)に対してかなり安全であると言いますが、さらに安全にしたい場合はbase(64)エンコーディングを使用してください($ remove配列をコメントアウトする)および/またはより少ない文字を切り捨てます。

// convert md5 to base64, remove undesirable characters and truncate to $length
function tinymd5($str, $length) { // $length 20-22 not advised unless $remove = '';
    // remove vowels to prevent undesirable words and + / which may be problematic
    $remove = array('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U', '+', '/');
    $salt = $str;
    do { // re-salt and loop if rebase removes too many characters
        $salt = $base64 = base64_encode(md5($salt, TRUE));
        $rebase = substr(str_replace($remove, '', $base64), 0, $length);
    } while ($length < 20 && substr($rebase, -1) == '=');
    return str_pad($rebase, min($length, 22), '='); // 22 is max possible length
}

$str = 'Lorem ipsum dolor sit amet 557726776';
echo '<br />' . md5($str);         // 565a0bf7e0ba474fdaaec57b82e6504a
$x = md5($str, TRUE);
echo '<br />' . base64_encode($x); // VloL9+C6R0/arsV7guZQSg==
echo '<br />' . tinymd5($str, 12); // VlL9C6R0rsV7
echo '<br />' . tinymd5($str, 17); // VlL9C6R0rsV7gZQSg
$x = md5(base64_encode($x), TRUE); // re-salt triggered < 20
echo '<br />' . base64_encode($x); // fmkPW/OQLqp7PTex0nK3NQ==
echo '<br />' . tinymd5($str, 18); // fmkPWQLqp7PTx0nK3N
echo '<br />' . tinymd5($str, 19); // fmkPWQLqp7PTx0nK3NQ
echo '<br />' . tinymd5($str, 20); // fmkPWQLqp7PTx0nK3NQ=
echo '<br />' . tinymd5($str, 22); // fmkPWQLqp7PTx0nK3NQ===
0
Tom Davenport

$ hashlen = 4;
$ cxtrong = TRUE;
$ sslk = openssl_random_pseudo_bytes($ hashlen、$ cxtrong);
$ Rand = bin2hex($ sslk);

エコー$ランド;

変数$ hashlenの値を変更することにより、ハッシュの長さ(2の倍数)を変更できます。

0

大きなアルファベットを使用してハッシュを短くすることができますが、それでも元の値に戻すことができます。

私はそれを実装しました ここ -たとえば、ハッシュee45187ab28b4814cf03b2b4224eb9747fBKxltZiQd7TFsUkOp26wになります-それは32から22文字になります。また、より大きなアルパハベットを使用すると、さらに少なくなる可能性があります。 Unicodeを使用する場合は、絵文字でハッシュをエンコードすることもできます...