Шифрование AES-128 с Base64 не работает одинаково в Java и PHP с более длинными строками - PullRequest
2 голосов
/ 21 марта 2012

Я пытался заставить шифрование / дешифрование работать одинаково в Java (Android) и PHP и давать одинаковые результаты для связи клиент-сервер.

Я использую код ниже для шифрования, но я не знаю, что с ним не так. Запуск как с одним и тем же ключом, так и с небольшими строками дает одно и то же зашифрованное значение, однако с более длинными строками я получаю два разных результата. 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 однако я получаю 4s5a0edsvwWt/3/enRe0wgJQD/0zL45NRb/r3p6L/Is= с PHP и 4s5a0edsvwWt/3/enRe0wgA0jk78zwWJr1xsosZbYUA= с Java. Я не уверен, что случилось, и я недостаточно осведомлен о криптографии.

Ответы [ 2 ]

3 голосов
/ 21 марта 2012

Основная проблема вашего Java-кода заключается в том, что вы не указываете режим шифрования и используемый алгоритм заполнения. Поэтому, какой режим шифрования и алгоритм заполнения используются, зависит от используемого поставщика шифрования, и в этой конкретной детали Android работает иначе, чем J2SE.

Если я выполню ваш код Java на J2SE, я получу тот же результат, что и вы с PHP. Это не изменится, если я изменю код для использования Cipher.getInstance("AES/ECB/PKCS5Padding");.

Поскольку изменяется только последний блок вашего зашифрованного текста, я предполагаю, что Android по умолчанию использует другой алгоритм заполнения.

2 голосов
/ 21 марта 2012

Тот факт, что у вас есть разные результаты для коротких и длинных строк, предполагает, что вы используете разные отступы для каждой реализации.

Убедитесь, что вы используете один и тот же тип заполнения как в Java, так и в своих реализациях php.

...