Переписать алгоритм PHP Rijndael на Java (Android)

Мне нужно кодировать строку в Java и PHP, где результат должен быть одинаковым.

Даны следующие условия:

  1. алгоритм: RIJNDAEL-128
  2. ключ: 5P443m2Q1R9A7f5r3e1z08642
  3. режим: ECB
  4. вектор инициализации: нет данных (поскольку мы используем ECB, IV игнорируются)

String to encode: 201412181656005P443m2Q1R9A7f5r3e1z08642

 <?php
class Cipher
{
private $securekey, $iv;

function __construct($textkey)
{
$this->securekey = $textkey;
$this->iv = mcrypt_create_iv(32);
}

function encryptR($input)
{
$enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->securekey, $input, MCRYPT_MODE_ECB, $this->iv);
return base64_encode($enc);
}

function decryptR($input)
{
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->securekey, base64_decode($input), MCRYPT_MODE_ECB, $this->iv));
}
}

$raw_text = '201412181656005P443m2Q1R9A7f5r3e1z08642';
$secretKey = '5P443m2Q1R9A7f5r3e1z08642';

$cipher = new Cipher($secretKey);
$encrypted = $cipher->encryptR($raw_text);
?>

Выходные данные: MbDHhIanWgySlMTOX + ItgVKudVLXbtj7ig2GMQacVM9JhyAPvVQxLJnHpEj / vhqW

encrypted = encrypt("201412181656005P443m2Q1R9A7f5r3e1z08642","5P443m2Q1R9A7f5r3e1z08642");

public class Crypt {

private final String characterEncoding = "UTF-8";
private final String cipherTransformation = "AES/ECB/PKCS5Padding";
private final String aesEncryptionAlgorithm = "AES";

public  byte[] decrypt(byte[] cipherText, byte[] key) throws Exception
{
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy);
cipherText = cipher.doFinal(cipherText);
return cipherText;
}

public byte[] encrypt(byte[] plainText, byte[] key) throws Exception
{
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
plainText = cipher.doFinal(plainText);
return plainText;
}

private byte[] getKeyBytes(String key) throws UnsupportedEncodingException{
byte[] keyBytes= new byte[16];
byte[] parameterKeyBytes= key.getBytes(characterEncoding);
System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
return keyBytes;
}

@SuppressLint("NewApi")
public String encrypt(String plainText, String key) throws Exception {
byte[] plainTextbytes = plainText.getBytes(characterEncoding);
byte[] keyBytes = getKeyBytes(key);
// Log.i("iv", ""+keyBytesIV);
return Base64.encodeToString(encrypt(plainTextbytes,keyBytes), Base64.DEFAULT);
}

@SuppressLint("NewApi")
public String decrypt(String encryptedText, String key) throws Exception {
byte[] cipheredBytes = Base64.decode(encryptedText, Base64.DEFAULT);
byte[] keyBytes = getKeyBytes(key);

return new String(decrypt(cipheredBytes, keyBytes), characterEncoding);
}

}

Выходные данные: wd0FHYpLbgdpHhcSql7VVCiKWJWN5hvP0W9F4sgKWAWeDcSjvfKWTM5LHBCZJSRw

Обновлено:

Я изменил отступы от NoPadding в PKCS5Padding

Это правильно? Я не уверен, потому что если вы посмотрите на код PHP. Не было указано никакого отступа (мое собственное предположение, основанное на синтаксисе).

Информация о Mcrypt

Дополнительная информация:

Прочитай это документ относительно заполнения (No Padding). Должно быть, было связано с проблемой.

3

Решение

Похоже, ваша версия PHP использует AES-128, который по определению использует 128-битные (16-байтовые) ключи. Однако похоже, что вы передали в 25-байтном ключе (5P443m2Q1R9A7f5r3e1z08642), что я не уверен, что делает PHP, когда это происходит.

Метод getKeyBytes () вашей версии Java возвращает только первые 16 байтов предоставленного ключа, поэтому он шифруется только этим.

Попробуйте усечь ключ в вашей версии PHP до 5P443m2Q1R9A7f5r и вы получите тот же результат. За исключением конечной части, которая может отличаться. В этот момент проблема будет заключаться в дополнительном заполнении. Вы можете применить pkcs5_pad Функция PHP на вашем открытом тексте, так что она соответствует вашей версии Java.

Все, что сказал, если это было только для учебных целей, это нормально. В противном случае для фактического использования важно, чтобы вы не используйте режим шифрования ECB.

3

Другие решения

Я изменился byte[] keyBytes= new byte[16]; в byte[] keyBytes= new byte[32]; в getKeyBytes метод то работал нормально.

0

По вопросам рекламы [email protected]