2012-01-04 9 views
2

次のコードを使用して、着信文字列をハッシュします。同じメソッドを複数回メソッドに適用すると、常に同じ結果が得られます。このシナリオは、パスワードハッシングとそれ以降の検証のためのものです。しかし、それは動作していないようです - 私は同じ入力文字列の2つの異なるブロブを得ました。私のコードに間違いや欠落がありますか?SHAは同じ文字列を異なるブロブにハッシュします

System.out.println("raw = " + raw.toString()); 

を行うには何もを持っていない[[email protected]のようなものをプリントアウトするために起こっていること:あなたが本当に十分な情報を与えられていないが、私はあなたがこのに気を取られている疑いがある

public synchronized String encrypt(String token) { 
    try { 
     MessageDigest sha = MessageDigest.getInstance("SHA"); 
     sha.reset(); 
     sha.update(token.getBytes("UTF-8")); 
     byte[] raw = sha.digest(); 
     System.out.println("raw = " + raw.toString()); 
     String hash = Base64.encodeBase64(raw).toString(); 
     return hash; 
    } catch (Exception e) { 
    } 

    return token; 
} 
+0

関連する言語のタグを追加します。私は 'Java'を追加することを忘れてしまったと思います。 –

+0

ありがとうございました。 – tom

+0

SHAは** NOT **の暗号化です。 – Dan

答えて

5

バイト配列のデータ代わりにhashを印刷してください。tokenが真に同じ場合は、と同じにする必要があります。

(ダンで述べたように、あなたの方法が不適切と命名された:ハッシュ暗号化ではありません。また、Exceptionまたはをキャッチしないでくださいちょうどこのような例外を飲み込むちょうど失敗にtokenを返すために、かなり奇妙に思えます、。。 )

EDIT:前述のように、Base64.encodeは実際には文字列を返すと想定していますが、そうでない場合もあります。私はthis base64 implementationをパブリックドメインであり、賢明なAPIを持っていることをお勧めします。エンコーディングの呼び出しは完全に適切な文字列を返します。もちろん、あなたは明示的にtoString()コールを必要としません。

+0

キャッチをありがとう!実際の暗号化に必要な追加手順は何ですか?私のコードは、パスワードの暗号化を行うと言われていたいくつかのサンプルコードの後に​​書かれました。 – tom

+1

@tom:パスワードの場合、可逆暗号化を使用しないでください。ハッシュもそれ自身では良くありません。少なくともハッシュをソルトし、適切なハッシングアルゴリズムを選択する必要があります。 (塩ハッシュ暗号の検索は、詳細を参照してください。) –

+0

説明のためにありがとうございました。 – tom

1

使用しているBase64クラスはわかりませんが、私はApache Commonsのものと仮定します。あなたはこれをやっている:何でもランダムなバイト配列にtoStringメソッドを呼び出している

String hash = Base64.encodeBase64(raw).toString(); 

Base64.encodeBase64()メソッドから返されます。そのため、毎回結果がランダムであり、オブジェクト参照をStringとして返すだけです。代わりにこれを試してみてください:

String hash = Base64.encodeBase64String(raw); 

EDIT

別の記事で指摘したように、文字列に直接変換することはおそらく悪い考えです。私はそれを反映するために私の答えを少し編集しました。