2011-01-22 7 views
4

ウェブサイトのプラットフォームをJavaからPHPに変更する必要があると思いますが、私はすべてのユーザーのパスワードを保持したいと思います...PHPでこれと同じJava SHA-1を入手できますか?

このコードでは、ハッシュ値をウェブサイトへのパスワード:

MessageDigest md = null; 
md = MessageDigest.getInstance("SHA"); 
md.update(plaintext.getBytes("UTF-8")); 
byte raw[] = md.digest(); 
hash = new Base64().encodeToString(raw).replaceAll("\n", "").replaceAll("\r", ""); 

私は、Javaコードは、パスワードのSHA-1ハッシュをしましたが、直前にそれがUTF-8にエンコードされたバイトだったし、その後それはBase64エンコードされたことと思います。

私はPHPコードを同じようにしたいと思います。すなわち、Javaと同じパスワードのハッシュと同じ値を返します.Sha-1ハッシングを実行しているPHPコードはそうではないようですハッシュのJava Base64でデコードされた値と比較した場合、同じSHA(-1、エンコードされたBase64ではなく、-1)を返します。PHPのパスワードがUTF-8でないという事実と関係がありますか最初にエンコードされたバイト(と私はPHPでそれを行うことができます)してください?

P.S. Javaで

別の奇妙な...私のパスワードはすべて28characters長い(このrnwn4zTNgH30l4pP8V05lRVGmF4=のような通常のもの)です...しかし、これらのパスワードハッシュのBase64().decode(hash)値が長い10文字(例[[email protected])です。

私はBase64が各3つのチャーター(28または27、パディング=チャーターを除いて、それらの10チャプターより3分の1大きい)を1文字追加したと思っています。 ??

さらに、PHPのSHA-1パスワードのハッシュ値は、dd94709528bb1c83d08f3088d4043f4742891f4fのように40文字(UTF-8 mysqlデータベース内)ですか?

+0

コードを適切に書式設定する必要があります。すべての行の前に4つのスペースまたはタブを置きます。 – Donovan

+0

@Alberteddu:コードを選択して '{}'アイコンをクリックすると、SOで実行できます。 – SyntaxT3rr0r

+2

'[B @ 14e1f2b'は' Base64()。decode(hash) 'の値ではありません。' ['+ ArrayType +' @ '+ hashCode]の形式の配列の通常のString表現です。あなたがしたいのは、単純に 'System.out.println(array_var);と書くのではなく、配列を反復することです。 – Progman

答えて

5

[[email protected]は間違いなくハッシュではありません。 byte[]からStringへの暗黙的な変換の結果です。

それは、あなたがこのような何かのようになります。

String decodedHash = Base64().decode(hash); // Produces [[email protected] 

をしかし、ハッシュの正しい表現はバイト配列である:

byte[] decodedHash = Base64().decode(hash); 
+0

私の間違いを指摘してくれてありがとう。しかし、適切なbyte []をStringに変換すると、PHPで得られる40文字が返されますか?私は不適切なフォーマットについて謝罪します(私はSOヌービーです)。 – Nubie

+0

@Nubie:PHPが16進値を生成した場合、結果の配列を16進文字列に変換して一致するかどうかを調べることができます。 – axtavt

+0

@axtavtは '[B @ 13e1f2b'の' @ 'の後の部分は実際はハッシュですが、明らかにNubieが望むものではありません。これはtoString()メソッドの出力です。本文は 'getClass()。getName()+" @ "+ Integer.toHexString(hashCode());' – stivlo

3

私は正常にSHAを計算するためにJavaで何-1のハッシュは、PHPのsha1()関数とまったく同じです。キーは、toHexStringを使用して、生のバイトを印刷可能な方法で表示することです。 PHP関数を使用していて、複雑なプロセスと同じ結果を得たい場合は、PHPで$ raw_outputパラメータをtrueに設定して、生のバイトを取得し、Base64を適用する必要があります。 Full source code

/** 
* Compute a SHA-1 hash of a String argument 
* 
* @param arg the UTF-8 String to encode 
* @return the sha1 hash as a string. 
*/ 
public static String computeSha1OfString(String arg) { 
    try { 
     return computeSha1OfByteArray(arg.getBytes(("UTF-8"))); 
    } catch (UnsupportedEncodingException ex) { 
     throw new UnsupportedOperationException(ex); 
    } 
} 

private static String computeSha1OfByteArray(byte[] arg) { 
    try { 
     MessageDigest md = MessageDigest.getInstance("SHA-1"); 
     md.update(arg); 
     byte[] res = md.digest(); 
     return toHexString(res); 
    } catch (NoSuchAlgorithmException ex) { 
     throw new UnsupportedOperationException(ex); 
    } 
} 

private static String toHexString(byte[] v) { 
    StringBuilder sb = new StringBuilder(v.length * 2); 
    for (int i = 0; i < v.length; i++) { 
     int b = v[i] & 0xFF; 
     sb.append(HEX_DIGITS.charAt(b >>> 4)).append(HEX_DIGITS.charAt(b & 0xF)); 
    } 
    return sb.toString(); 
} 
1

PHPのsha1()は、デフォルトでは16進数として出力の各バイトを符号化していますが、2番目の引数としてtrueを渡すことによって、生の出力を得ることができます:

$digest = sha1($password, true); // This returns the same string of bytes as md.digest() 

その後base64_encodeにダイジェストを渡します

base64_encode(sha1($password, true)); 

これは、javaコードとまったく同じSHA-1ハッシュを返します。

関連する問題