2012-02-10 13 views
0

** 問題解決。私の入力は、EditTextから関数を実行するJavaへの途中で変更されました。それは本当に明白でした。私は本当にばかげている。みんなの時間を無駄にして本当に残念です...android md5暗号化がmysqlまたはphpと一致しませんか?

私はMD5を使用して文字列を暗号化し、MySQLとPHPで使用されているmd5関数の結果と一致しないことがわかりました。例えば

PHP/MYSQL: 文字列:passwordハッシュ:5f4dcc3b5aa765d61d8327deb882cf99

アンドロイド: 文字列:passwordハッシュ:bc4a7f3b32b2a85688a53c49df19cd95

私は検索とstackoverflowの上の人々を見てきました同じ問題を抱えていますが、まだ回答が見つかりませんでした。 私は多くの方法を使用して、文字コードを変更しようとしましたが、それでも一致することはありません。すべてのヘルプをいただければ幸いです

public static String md5(String input){ 
     String result = input; 
     if(input != null) { 
      MessageDigest md; 
      try { 
       md = MessageDigest.getInstance("MD5"); 
      md.update(input.getBytes()); 
      BigInteger hash = new BigInteger(1, md.digest()); 
      result = hash.toString(16); 
      if ((result.length() % 2) != 0) { 
       result = "0" + result; 
      } 
      }catch (NoSuchAlgorithmException e) { 
       e.printStackTrace(); 
       return null; 
      } 
     } 
     return result; 
    } 

は、ここで私は現在、(これは動作しません)私のプロジェクトに保存されている機能です。

+1

うーん...標準のSun JVM(1.6)でコードを実行すると、正しい出力が得られます。 AndroidのデフォルトのcharsetはUTF-8でなければならないので、 'input.getBytes()'とは関係ないと思います。 'MessageDigest'と何か関係があります。それにもかかわらず、 'getBytes(" UTF-8 ")'を明示的に使って試してみます。 – Peter

+0

文字列をバイト配列に変更するときに、同じ文字列エンコーディングを使用しようとしましたか? – Selvin

+1

スニペットはプラットフォームのデフォルトのエンコーディングに頼っているようです(AndroidはUTF-8を既に使用していますが)。入力に空白がないことは確かですか?別のスニペットについては、これも参照してください:http://stackoverflow.com/questions/5494447/what-will-be-the-android-java-equivalent-of-md5-function-in-php – BalusC

答えて

1

2つのこと...まず、BigIntegerを使用しないでください。バイト配列を16進表現に変換する必要があります。つまり、正確に行うように設計されたコードを使用してください(Apache Common Codecなど)。 MD5の出力に焦点を当てたいときは、変換の問題を徹底的に追うことができなくなります。編集:さて、コードが問題ではなかったように聞こえますが、入力を受けていましたが、ここでも変更を行います。それはあなたがより明確に達成しようとしているものを表現するより読みやすいコードに終わるはずです。

第二に、このコード:

md.update(input.getBytes()); 

...は、プラットフォームのデフォルトのエンコーディングを使用しています。それは決して良い考えではありません。プラットフォームのデフォルトのエンコーディングがわかっていても、エンコーディングを明示的に指定してください。この場合は無害ですが、非ASCIIテキストを処理する必要がある場合に備えて、コードを修正する必要があります。

+1

入力の例にはASCII互換の文字しか含まれていないため、文字エンコーディングを指定してもOPの具体的な問題の原因にはなりません。さらに、なぜBigIntegerが悪い考えであるのか本当に説明していないので、私はそれに興味があります。 – BalusC

+0

@BalusC:この特定のケースでは、ASCII文字しか得られませんが、デフォルトのエンコーディングを使用してそれを残してしまうと、バグが起きるのを待っているので、それは言及しません。私は*問題がここの 'BigInteger'にあると思う - なぜそれが失敗するのか分からない(それはデスクトップJavaで私にとってはうまくいく)が、根本的にはそうではないものを実行する賢明な方法のようには見えない大きな整数について - バイトの約16進表現です。 –

+0

答えは、それがOPの具体的な問題の2つの可能な原因の1つであることを暗示しました(これはこの特定のケースでは真実ではありません)。さて、あなたは、BigIntegerが考えられる原因であることを、単純に推測していました。私は 'BigInteger'クラスを悪用してもうまくいくはずなので、なぜ失敗するのかという技術的な理由は疑問です。 – BalusC

0

この問題は、おそらく文字エンコーディングによるものです。私は、あなたが異なる文字コードを試したと言ったことは知っていますが、あなたのコードはそれを持っていません。

はこの質問への回答を確認してください: How can I generate an MD5 hash?

するMessageDigestクラスは、MD5 ダイジェストのインスタンスを提供することができます。

常に文字列と暗号クラスで作業する場合は、 に必ずバイト表現を挿入するエンコードを指定してください。 の場合は、string.getBytes()を使用するとプラットフォームのデフォルトが使用されます。 (未 すべてのプラットフォームで同じデフォルトを使用)

byte[] bytesOfMessage = yourString.getBytes("UTF-8");

+0

あなたは完全に正しいですが、ASCII文字だけを含む単語については問題にはなりません。実際にはすべての文字エンコーディングで同じバイトが生成されます(EBCDICのようにASCIIに匹敵する古代のものを期待します)。 ASCII範囲を超える文字だけが、使用される文字エンコーディングに応じて異なるバイトを与えることがあります。 – BalusC

関連する問題