php crypt()の出力を有効なMD5に変換できますか?
-
19-08-2019 - |
質問
PHP関数crypt()
を使用して暗号化された文字列があります。
出力は次のようになります。
$1$Vf/.4.1.$CgCo33ebiHVuFhpwS.kMI0
$1$84..vD4.$Ps1PdaLWRoaiWDKCfjLyV1
$1$or1.RY4.$v3xo04v1yfB7JxDj1sC/J/
crypt()はMD5アルゴリズムを使用していると思いますが、出力は有効なMD5ハッシュではありません。
生成されたハッシュを有効なMD5ハッシュ(16バイトの16進値)に変換する方法はありますか?
更新:
これまでの回答に感謝します。使用されている暗号化機能が何らかのMD5アルゴリズムを使用していると確信しています。私がやろうとしているのは、持っている出力を次のようなMD5ハッシュに変換することです。
9e107d9d372bb6826bd81d3542a419d6
e4d909c290d0fb1ca068ffaddf22cbd0
d41d8cd98f00b204e9800998ecf8427e
(ウィキペディアから取得)
持っているハッシュから上記のようなハッシュに変換する方法はありますか?
解決
OK、だからこの答えは一年遅れかもしれませんが、試してみます。あなた自身の答えでは、crypt()
はハッシュを実行する前にソルトにいくつかの興味深い変換を行うFreeBSD MD5を使用していることに注意するので、私が提供しようとしているものの結果はmd5()
の呼び出しの結果。ただし、表示される出力と使用される形式の唯一の違いは、表示される出力が次のようにエンコードされることです
$1$ # this indicates that it is MD5
Vf/.4.1. # these eight characters are the significant portion of the salt
$ # this character is technically part of the salt, but it is ignored
CgCo33eb # the last 22 characters are the actual hash
iHVuFhpw # they are base64 encoded (to be printable) using crypt's alphabet
S.kMI0 # floor(22 * 6 / 8) = 16 (the length in bytes of a raw MD5 hash)
私の知る限り、cryptで使用されるアルファベットは次のようになります。
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
したがって、これらすべてを念頭に置いて、22文字のcrypt-base64ハッシュを32文字のbase16(16進数)ハッシュに変換する方法を次に示します。
まず、base64(カスタムアルファベット付き)を生の16バイトMD5ハッシュに変換するものが必要です。
define('CRYPT_ALPHA','./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
/**
* Decodes a base64 string based on the alphabet set in constant CRYPT_ALPHA
* Uses string functions rather than binary transformations, because said
* transformations aren't really much faster in PHP
* @params string $str The string to decode
* @return string The raw output, which may include unprintable characters
*/
function base64_decode_ex($str) {
// set up the array to feed numerical data using characters as keys
$alpha = array_flip(str_split(CRYPT_ALPHA));
// split the input into single-character (6 bit) chunks
$bitArray = str_split($str);
$decodedStr = '';
foreach ($bitArray as &$bits) {
if ($bits == '$') { // $ indicates the end of the string, to stop processing here
break;
}
if (!isset($alpha[$bits])) { // if we encounter a character not in the alphabet
return false; // then break execution, the string is invalid
}
// decbin will only return significant digits, so use sprintf to pad to 6 bits
$decodedStr .= sprintf('%06s', decbin($alpha[$bits]));
}
// there can be up to 6 unused bits at the end of a string, so discard them
$decodedStr = substr($decodedStr, 0, strlen($decodedStr) - (strlen($decodedStr) % 8));
$byteArray = str_split($decodedStr, 8);
foreach ($byteArray as &$byte) {
$byte = chr(bindec($byte));
}
return join($byteArray);
}
生データを取得したら、それを期待する16進形式に変換するメソッドが必要になりますが、これは簡単ではありません。
/**
* Takes an input in base 256 and encodes it to base 16 using the Hex alphabet
* This function will not be commented. For more info:
* @see http://php.net/str-split
* @see http://php.net/sprintf
*
* @param string $str The value to convert
* @return string The base 16 rendering
*/
function base16_encode($str) {
$byteArray = str_split($str);
foreach ($byteArray as &$byte) {
$byte = sprintf('%02x', ord($byte));
}
return join($byteArray);
}
最後に、cryptの出力にはこのプロセスに必要ではない(そして実際には使用できない)多くのデータが含まれているため、これら2つを結び付けるだけでなく、 cryptからの出力の入力。
/**
* Takes a 22 byte crypt-base-64 hash and converts it to base 16
* If the input is longer than 22 chars (e.g., the entire output of crypt()),
* then this function will strip all but the last 22. Fails if under 22 chars
*
* @param string $hash The hash to convert
* @param string The equivalent base16 hash (therefore a number)
*/
function md5_b64tob16($hash) {
if (strlen($hash) < 22) {
return false;
}
if (strlen($hash) > 22) {
$hash = substr($hash,-22);
}
return base16_encode(base64_decode_ex($hash));
}
これらの関数を考えると、3つの例のbase16表現は次のとおりです。
3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154
もちろん、それらは常に有効であり、フォーマットが異なるだけであることを覚えておくことが重要です。
他のヒント
$ 1 $は確かにこれがMD5ハッシュであることを意味しますが、cryptはランダムなソルトを生成します。これが、異なるMD5値を見つける理由です。生成されたソルトを含めると、同じ結果が得られます。
ソルトは、ハッシュとして出力でbase64エンコードされます。
使用されるアルゴリズムは、システム全体のパラメーターです。通常、これはMD5です、あなたは正しいです。
元の質問に対する答えは「いいえ」と考えています。ある形式から別の形式に変換することはできません。
php crypt()によって生成されたハッシュは、Poul-Henning Kampによって作成されたFreeBSD MD5ハッシュ実装のバージョンによって生成されたようです。
ドキュメントによると、これはシステムによって異なります。 saltパラメーターを設定することにより、使用するアルゴリズムを強制できます。ドキュメントから:
暗号化タイプは、 salt引数。インストール時に、 PHPは、 関数を暗号化し、塩を受け入れます 他の暗号化タイプの場合。塩がない場合 提供され、PHPは自動生成します 標準の2文字ソルト デフォルト、デフォルトの暗号化を除く システムのタイプはMD5です。 ランダムなMD5互換の塩が 生成されます。
crypt()は、標準のUnix DESベースの暗号化アルゴリズムまたはシステムで使用可能な代替アルゴリズムを使用して、暗号化された文字列を返します。
md5()
関数が必要な場合:
<!>#187を使用してstrのMD5ハッシュを計算します。 RSA Data Security、Inc. MD5メッセージダイジェストアルゴリズム。そのハッシュを返します。
オプションのraw_outputがTRUEに設定されている場合、代わりにmd5ダイジェストが長さ16の生のバイナリ形式で返されます。 デフォルトはFALSEです。