0

I am googling and testing solution for a while and so far no success. There is always some problem with it. Following code is "working" (meaning do not show any error while it is running) on Android Kitkat and higher, but decrypted files are not readable. Why?

final static byte[] iv = new byte[16];//ADDED
final static int buffer = 102400;
final static String encryptionType = "AES/CFB8/NoPadding";//CHANGED TO DIFFERENT TYPE

static void encrypt(String password, File fileInput, File fileOutput) throws Exception {

    IvParameterSpec ivParams = new IvParameterSpec(iv);//ADDED

    FileInputStream fis = new FileInputStream(fileInput);
    FileOutputStream fos = new FileOutputStream(fileOutput);

    SecretKeySpec sks = new SecretKeySpec(password.getBytes("UTF-8"), encryptionType);

    Cipher cipher = Cipher.getInstance(encryptionType);
    //cipher.init(Cipher.ENCRYPT_MODE, sks);REPLACED
    cipher.init(Cipher.ENCRYPT_MODE, sks, ivParams);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);

    int b;
    byte[] d = new byte[buffer];
    while ((b = fis.read(d)) != -1) {
        cos.write(d, 0, b);
    }

    cos.flush();
    cos.close();
    fis.close();
}

static void decrypt(String password, File fileInput, File fileOutput) throws Exception {

    IvParameterSpec ivParams = new IvParameterSpec(iv);//ADDED

    FileInputStream fis = new FileInputStream(fileInput);
    FileOutputStream fos = new FileOutputStream(fileOutput);

    SecretKeySpec sks = new SecretKeySpec(password.getBytes("UTF-8"), encryptionType);

    Cipher cipher = Cipher.getInstance(encryptionType);
    //cipher.init(Cipher.ENCRYPT_MODE, sks);REPLACED
    cipher.init(Cipher.DECRYPT_MODE, sks, ivParams);
    CipherInputStream cis = new CipherInputStream(fis, cipher);

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

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

EDIT: After I changed type to "AES/CFB8/NoPadding", it seems to be ok, there is no error in process, but decrypted file is not readable.

Michalsx
  • 2,515
  • 3
  • 23
  • 39
  • try the below link it's help you https://stackoverflow.com/questions/20227/how-do-i-use-3des-encryption-decryption-in-java – PLP Sep 12 '17 at 08:49
  • Check out my answer here https://stackoverflow.com/questions/42560868/storing-credentials-in-the-android-app/42716982#42716982 – Ricardo Sep 12 '17 at 14:34
  • I checked both link and both didn´t help. Can you clarify, how this should help? – Michalsx Sep 12 '17 at 20:07

2 Answers2

1

The problem in the decrypt method is caused by this line:

cipher.init(Cipher.ENCRYPT_MODE, sks);

the mode needs to Cipher.DECRYPT_MODE, so the line should be

cipher.init(Cipher.DECRYPT_MODE, sks);

Other issues are the use of the long obsolete DESede algorithm, the lack of any IV generation and handling, the absence of a good password-based key derivation algorithm, and the lack of any MAC on the ciphertext. Correctly using AES GCM mode with proper nonce generation and handling, and use of PBKDF2 (which is available on Android and Oracle Java) would represent significant improvements.

You don't supply an IV, so one is generated for you automatically. You must find a way to transmit this IV to the recipient. Typically the IV/Nonce is prepending to the ciphertext and stripped off by the recipient in order to decrypt the data. CipherInputStream/CipherOutputStream does not do this for you, so you must do it on your own.

President James K. Polk
  • 36,717
  • 16
  • 86
  • 116
0

I finally solve this problem by using shorter password. I am not sure why, but on Android 7 and 8, there is no problem with long password, but same password on Android 4.4 leads to crazy errors and brake encryption.

Michalsx
  • 2,515
  • 3
  • 23
  • 39