2012-03-21 5 views
2

Java(Android)およびPHPで同じ暗号化/復号化を実行し、クライアント/サーバー通信。Base64エンコーディングを使用したAES-128暗号化は、JavaおよびPHPで長い文字列を使用しても同じ動作をしません

私は以下のコードを暗号化に使用していますが、何が問題なのか分かりません。同じキーと小さな文字列で両方を実行すると同じ暗号化値が生成されますが、長い文字列では2つの異なる結果が得られます。 PHP:

$str = 'test1234test1234'; 

$key = 'TESTKEYTESTKEY12'; 

$block = mcrypt_get_block_size('des', 'ecb'); 

$pad = $block - (strlen($str) % $block); 
$str .= str_repeat(chr($pad), $pad); 
echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB)); 

とJavaで(Android上):

public static String encryptTest() { 
    String cleartext = "test1234test1234"; 
    String key = "TESTKEYTESTKEY12"; 
    byte[] raw = key.getBytes(); 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
    try { 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
     byte[] encrypted; 
     encrypted = cipher.doFinal(cleartext.getBytes()); 
    return new String(Base64.encode(encrypted,Base64.DEFAULT)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

がString test1234でこれを実行するには与える:両方の実装で8i4KEe82TQl0Zdlc14fwAg==を。 文字列ではtest1234test1234ですが、PHPで4s5a0edsvwWt/3/enRe0wgJQD/0zL45NRb/r3p6L/Is=、Javaで4s5a0edsvwWt/3/enRe0wgA0jk78zwWJr1xsosZbYUA=と表示されます。私は何が間違っているのか分かりませんし、私は暗号について十分知識がありません。

+0

これを言うためにPHPを変更するとどうなりますか? $ str。= str_repeat(chr(0)、$ pad); – Sparky

答えて

3

Javaコードの主な問題は、暗号モードと使用されているパディングアルゴリズムを指定していないことです。したがって、どの暗号モードと埋め込みアルゴリズムが使用されるかは、使用される暗号プロバイダによって異なります。この具体的な詳細では、AndroidはJ2SEとは異なる動作をします。

JavaコードをJ2SEで実行すると、PHPの場合と同じ結果になります。 Cipher.getInstance("AES/ECB/PKCS5Padding");を使用するようにコードを変更すると、これは変更されません。

暗号文の最後のブロックだけが変更されるため、Androidはデフォルトで異なるパディングアルゴリズムを使用していると仮定します。

+0

これで問題なく動作しました。私はJavaのコードを '' AES/ECB/PKCS5Padding ''を使うように変更しましたが、これは当初は改善されませんでしたが、このブロックサイズを '$ block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128、MCRYPT_MODE_ECB);'で使用しました。異なる文字列でうまく動作します。ありがとう。 –

2

短い文字列と長い文字列の結果が異なることは、実装ごとに異なるpaddingを使用していることを示しています。

JavaとPHPの両方の実装で同じタイプの埋め込みを使用していることを確認してください。

関連する問題