Зашифруйте файл с помощью AES-128 в PHP и расшифруйте его в Android

1

Мне нужно зашифровать файл с помощью AES-128 в PHP и расшифровать его на Android.

Я использую следующий код. Я успешно зашифровал и расшифровал его с помощью PHP-кода, но мне нужно расшифровать его с помощью Android из моего приложения.

PHP-код:

$key= "asdfghjklzxccvbn";   
$in_filename = $_FILES["fileToUpload"]["tmp_name"];
$aes_filename =$target_dir."encry_".$_FILES["fileToUpload"]["name"];
$decry_filename =$target_dir."decry_".$_FILES["fileToUpload"]["name"];

//encrypt file
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = '1234567890123456';

$fin = fopen($in_filename, "rb");
$fcrypt = fopen($aes_filename, 'wb');
fwrite($fcrypt, $iv);
$opts = array('iv'=>$iv, 'key'=>$key, 'mode'=>'cbc');
stream_filter_append($fcrypt, 'mcrypt.rijndael-128', STREAM_FILTER_WRITE,     $opts);
while (!feof($fin))
{
    fwrite($fcrypt, fread($fin, 8192));
}
fclose($fcrypt);
fclose($fin);

Мой Android-код для дешифрования зашифрованного файла:

 // encripted file stored in android device for decrypt
 String uri= Environment.getExternalStorageDirectory().toString();
 uri=uri+"/encry_file.mp4";
 File file = new File(uri.toString());
 FileInputStream fis = new FileInputStream(file);
 spec =getIV();

 FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/decrypted.mp4");
 SecretKeySpec sks = new SecretKeySpec("asdfghjklzxccvbn".getBytes(),
          "AES");
 Cipher cipher = Cipher.getInstance("AES");
 cipher.init(Cipher.DECRYPT_MODE, sks, spec);
 CipherInputStream cis = new CipherInputStream(fis, cipher);

 int b;
 byte[] d = new byte[8192];
 while ((b = cis.read(d)) != -1) {
    fos.write(d, 0, b);
 }
 fos.flush();
 fos.close();
 cis.close();

получить функцию iv

public AlgorithmParameterSpec getIV() {
    byte[] iv = { 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6 };
    IvParameterSpec ivParameterSpec;
    ivParameterSpec = new IvParameterSpec(iv);

    return ivParameterSpec;
}

Андроид код будет генерировать файл, но он не читается. проверьте мой код, я делаю правильные коды или если он содержит какие-либо проблемы. помогите мне решить его

  • 0
    я не понимаю тебя. пожалуйста, сделайте это конкретным .. я новичок в этой вещи. Где я должен сделать изменения и что
Теги:
encryption
aes

1 ответ

1

Режим и отступы не совпадают. Вы используете AES/CBC/ZeroPadding (нотацию Java) в PHP, но в Java вы используете Cipher.getInstance("AES") который (возможно) по умолчанию использует Cipher.getInstance("AES/ECB/PKCS5Padding"). Всегда используйте полное описание шифрования:

Cipher cipher = Cipher.getInstance("AES/CBC/ZeroPadding", "BC");

(Это не решает проблему.)

Вы не используете тот же IV. Символ '1' и байт 1 - это не одно и то же, потому что '1' - фактически байт 49.

byte[] iv = { 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54 };

Поскольку BouncyCastles/SpongyCastles ZeroPadding не совсем то же самое, что и заполнение нулей mcrypt, вы должны использовать Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); чтобы проанализировать последние 16 байтов дешифрования и удалить конечные 0x00 байт.

Вот как это сделать в вашем случае:

int b;
byte[] d = new byte[8192];
byte[] p = null;
int holdOff;
while ((b = cis.read(d)) != -1) {
    holdOff = Math.max(b - cipher.getBlockSize(), 0);
    if (p != null) {
        fos.write(p, 0, p.length);
        Arrays.fill(p, 0);
    }
    if (p == null) {
        p = new byte[cipher.getBlockSize()];
    }
    System.arraycopy(d, holdOff, p, 0, p.length);

    fos.write(d, 0, holdOff);
}

// here p contains the end of the plaintext followed by padding bytes
// remove padding:
int i = cipher.getBlockSize() - 1;
while(i >= 0 && p[i] == 0) {
    i--;
}
// write remaining bytes
fos.write(Arrays.copyOf(p, i+1), 0, i+1);

fos.flush();
fos.close();
cis.close();

Идея заключается в том, что вы не записываете последние 16 байтов в файл и обрабатываете их отдельно, потому что последний 16-байтовый файл расшифровки может содержать 0x00 байт, которые необходимо удалить.


Другие соображения:

  • Всегда произвольно генерируйте IV для каждого шифрования. Он не должен быть секретным, но он должен быть непредсказуемым. Вы можете отправить его вместе с зашифрованным текстом, например, поставив его перед зашифрованным текстом.

  • Аутентифицируйте свои зашифрованные тексты, запустив над ним HMAC (encrypt-then-MAC). Прежде чем приступать к расшифровке, вам необходимо проверить MAC на стороне приемника, чтобы убедиться, что он был обработан на этом пути.

  • 0
    Я изменил свой код Android согласно вашему комментарию, но все еще не работает.
  • 0
    Есть ли ошибки? Если файл существует, чем полученный файл отличается от ожидаемого файла? Длина одинакова? Отличаются ли первый, последний или все байты?
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню