結果が同じでなければならない場合、Javaとphpでクリアテキストをエンコードする必要があります。
次の条件が与えられます。
- アルゴリズム: RIJNDAEL-128
- キー: 1234567890123456
- モード: cfb
- 初期化ベクトル: 1234567890123456
次のコードは機能し、最初の要件と 2 番目の要件を満たしますが、ECB をモードとして使用するため、初期化ベクトルを使用しません。
PHP:
<?php
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$cleartext = 'abcdefghijklmnop';
$key128 = '1234567890123456';
$iv = '1234567890123456';
if (mcrypt_generic_init($cipher, $key128, $iv) != -1) //Parameter iv will be ignored in ECB mode
{
$cipherText = mcrypt_generic($cipher,$cleartext );
mcrypt_generic_deinit($cipher);
printf(bin2hex($cipherText));
}
?>
出力: fcad715bd73b5cb0488f840f3bad7889
ジャワ:
public class AES {
public static void main(String[] args) throws Exception {
String cleartext = "abcdefghijklmnop";
String key = "1234567890123456";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(cleartext.getBytes());
System.out.println(asHex(encrypted));
}
public static String asHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
}
出力は次のとおりです (PHP バージョンと同じ): fcad715bd73b5cb0488f840f3bad7889
要件 3 と 4 を満たすために、コードが次のようになるように、PHP バージョンでモードを MCRYPT_MODE_CFB に変更しました。
<?php
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CFB, '');
$cleartext = 'abcdefghijklmnop';
$key128 = '1234567890123456';
$iv = '1234567890123456';
if (mcrypt_generic_init($cipher, $key128, $iv) != -1) //Parameter iv will be ignored in ECB mode
{
$cipherText = mcrypt_generic($cipher,$cleartext );
mcrypt_generic_deinit($cipher);
printf(bin2hex($cipherText));
}
?>
これにより、次の出力が得られます: 14a53328feee801b3ee67b2fd627fea0
JAVA バージョンでもモードを適応させ、iv を Cipher オブジェクトの init 関数に追加しました。
public class AES {
public static void main(String[] args) throws Exception {
String cleartext = "abcdefghijklmnop";
String key = "1234567890123456";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec("1234567890123456".getBytes()));
byte[] encrypted = cipher.doFinal(cleartext.getBytes());
System.out.println(asHex(encrypted));
}
public static String asHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
}
しかし、ここでの出力は 141eae68b93af782b284879a55b36f70 で、PHP バージョンとは異なります。
JAVA と PHP のバージョンの違いを知っている人はいますか?