2017-04-04 10 views
25

私はPHPで暗号化スクリプトのキージェネレータを書いています。私はJavaで書いたクラスと互換性があり、リソースを共有できるようにしたいと思います。なぜこれらのPHPとJavaのキージェネレータは異なる出力を生成するのですか?

PHPコード:

public function keyGen($key, $rounds) { 
    for($i = 0; $i < $rounds; $i++) { 
     $key = substr(base64_encode(md5($key)), 0, 16); 
     echo $i . " " . $key . PHP_EOL; // debugging // 
    } 
    return $key; 
} 

Javaコード:

public static String keyGen(String key, int rounds) { 
    try { 
     for(int i = 0; i < rounds; i++) { 
      byte[] md5 = MessageDigest.getInstance("MD5").digest(key.getBytes("UTF-8")); 
      String md5h = (new BigInteger(1, md5)).toString(16); 
      key = Base64.getEncoder().encodeToString(md5h.getBytes()).substring(0, 16); 
      System.out.println(Integer.toString(i) + " " + key); // debugging // 
     } 
    } catch(Exception ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
    return key; 
} 

PHPのデバッグ出力:

0 MWExZGM5MWM5MDcz 
1 NDVkZmMxNWVjNWZi 
2 ODY5YzVkODBhNTRh 
3 ZGE2OTNiOWMxOWM1 
4 OTcxMTY3MzgxMmRk 
5 NWNjNDI2N2IzMDlj 
6 NGVkYzY0YjVkMWUy 
7 MjdhMGU4NjhhNmU3 
8 OWY5OGE3ZGZiODZl 
9 Y2I1ZjBkNjRmMjkx 
10 YTk5NDA1MGI1OWY1 
11 YzRmYWE5ZTk0ZDdl 
12 NDBiZWZkNmQ5Yjhj 
13 MzQyNzcwNGRjMTYw 
14 N2U4ZmUxOGMyNWYx 
15 MjBjOTZhNGE4ZDQ1 
16 MjdmMzkwMzI0NDdj 
17 YjM4NDI0YWU0YzUw 
18 NDRiNjA1MWUwOGZi 
19 MGI1YmIyMDViMGYz 

のJavaデバッグ出力:

0 MWExZGM5MWM5MDcz 
1 NDVkZmMxNWVjNWZi 
2 ODY5YzVkODBhNTRh 
3 ZGE2OTNiOWMxOWM1 
4 OTcxMTY3MzgxMmRk 
5 NWNjNDI2N2IzMDlj 
6 NGVkYzY0YjVkMWUy 
7 MjdhMGU4NjhhNmU3 
8 OWY5OGE3ZGZiODZl 
9 Y2I1ZjBkNjRmMjkx 
10 YTk5NDA1MGI1OWY1 
11 YzRmYWE5ZTk0ZDdl 
12 NDBiZWZkNmQ5Yjhj 
13 MzQyNzcwNGRjMTYw 
14 N2U4ZmUxOGMyNWYx 
15 MjBjOTZhNGE4ZDQ1 
16 MjdmMzkwMzI0NDdj 
17 YjM4NDI0YWU0YzUw 
18 NDRiNjA1MWUwOGZi 
19 YjViYjIwNWIwZjMy 

これは19番目のループまで期待どおりに動作します。なぜそれは後に別の出力を生成するのですか?

+0

あなたは[どのように "良い"ランダムmd5ハッシュを作成するのですか?](http://stackoverflow.com/a/24037589/1255289) – miken32

+1

私はあなたの鍵を知らないのでテストしませんが、あなたの問題はこれによって引き起こされる可能性があります: 'md5h.getBytes()'。投稿したJavaコードの4行目では、UTF-8のエンコーディングを使用していますが、6行目はエンコーディングを使用していません。 –

+0

再現を試みるために鍵を与えます。 –

答えて

31

Javaでは、BigDecimalをtoString(int base)メソッドで16進文字列に変換しても、先行ゼロは出力されません。

中間ステップ(md5ハッシュコードを16進文字列に変換)の出力を印刷することでこれを見つけることができます.NYではb5bb205b0f32a7bf2a80fc870cbd2b7を与えるJavaでは0b5bb205b0f32a7bf2a80fc870cbd2b7となります。 1つの先行ゼロとの違いだけですが、base64エンコーディングを適用した後、それらは非常に異なって見えます。

先行ゼロを取得する簡単な方法は、String.formatメソッドを使用することです。このラインと

String md5h = (new BigInteger(1, md5)).toString(16); 

は、この行に置き換え

String md5h = String.format("%032x", new BigInteger(1, md5)); 

を、あなたのPHPコードと同じ出力が得られます。

関連する問題