MySQL MD5とJava MD5が等しくない
-
06-07-2019 - |
質問
MySQLの次の関数
MD5( 'secret')
は 5ebe2294ecd0e0f08eab7690d2a6ee69 を生成します
同じ出力を生成するJava関数が欲しいです。しかし
public static String md5( String source ) {
try {
MessageDigest md = MessageDigest.getInstance( "MD5" );
byte[] bytes = md.digest( source.getBytes("UTF-8") );
return getString( bytes );
} catch( Exception e ) {
e.printStackTrace();
return null;
}
}
private static String getString( byte[] bytes ) {
StringBuffer sb = new StringBuffer();
for( int i=0; i<bytes.length; i++ ) {
byte b = bytes[ i ];
sb.append( ( int )( 0x00FF & b ) );
if( i+1 <bytes.length ) {
sb.append( "-" );
}
}
return sb.toString();
}
生成
94-190-34-148-236-208-224-240-142-171-118-144-210-166-238-105
解決
16進数でエンコードを試してください。始めるために... 16進数で94は5Eです。
**編集:** getStringメソッドを変更してみてください:
private static String getString( byte[] bytes )
{
StringBuffer sb = new StringBuffer();
for( int i=0; i<bytes.length; i++ )
{
byte b = bytes[ i ];
String hex = Integer.toHexString((int) 0x00FF & b);
if (hex.length() == 1)
{
sb.append("0");
}
sb.append( hex );
}
return sb.toString();
}
他のヒント
交換
sb.append( ( int )( 0x00FF & b ) );
if( i+1 <bytes.length ) {
sb.append( "-" );
}
by
String hex = Integer.toHexString((int) 0x00FF & b);
if (hex.length == 1) sb.append("0");
sb.append( hex );
これは、Apache Commons Codecライブラリ( http:/のユーティリティクラスを使用して、1行に短縮できます。 /commons.apache.org/codec )
String md = org.apache.commons.codec.digest.DigestUtils.md5hex("whatever");
これら2つは等しいです。 Javaのものは10進数で表示されます。 16進数に変換します。
10進数のバイトを16進数に変換することを検討してください。たとえば、94ベース10は5eベース16です。
それは、ベースが異なるためです。 MySQL MD5の結果は16進数、Java MD5は10進数です。
さらに手助けをしたいのですが、数学が悪臭を放ちます。私の友人は、PHPでベース16チェックサムからベース10チェックサムを生成するのを手伝いましたが、スクリプトを失いました。これに基づいて答えが見つかることを願っています。
String password = org.springframework.util.DigestUtils.md5DigestAsHex("password".getBytes())
System.out.println(password)
どのように行うかを見てください、コードは自己説明可能です!
Javaコード:
public static void main(String a[]) throws NoSuchAlgorithmException {
String passClear = "cleartext";
MessageDigest md5 = MessageDigest.getInstance("MD5"); // you can change it to SHA1 if needed!
md5.update(passClear.getBytes(), 0, passClear.length());
System.out.printf("MD5: %s: %s ", passClear, new BigInteger(1, md5.digest()).toString(16));
}
出力:
MD5:cleartext:5ab677ec767735cebd67407005786016
同じハッシュを生成するMySQLクエリ:
SELECT md5( 'cleartext' );
出力:
md5( 'cleartext')
5ab677ec767735cebd67407005786016
車輪を再発明するのではなく、Apache commons codec( http://commons.apache.org/codecを試してください。 / )Hex.encodeHex(byte [])
で16進エンコードを処理しますprivate String encodeAsMD5(String password) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(password.getBytes());
return new String(Hex.encodeHex(bytes));
}
catch(Exception e) {
e.printStackTrace();
return null;
}
}
Apache Commons Codecライブラリのユーティリティクラスを使用します。 http://commons.apache.org/codec/
String password = org.apache.commons.codec.digest.DigestUtils.md5Hex("password");
System.out.println(password);