Criptografia Java AES para Android

Atualmente, estou criando um aplicativo Android que inclui criptografar uma String com o AES. Mas, por algum motivo, meu aplicativo não descriptografa corretamente. Tentei alterar o formato Base64, mas ele não o corrige. O código é semelhante ao exemplo emCriptografia Android com a API de criptografia Android

Alguém sabe onde eu errei com minhas funções? Como ele não decodifica para a mesma string que minha string codificada ("pls").

Sua ajuda é muito apreciada.

byte[] a = encryptFIN128AES("pls");
String b = decryptFIN128AES(a);
Log.e("AES_Test", "b = " + b);


/**
 * Encrypts a string with AES (128 bit key)
 * @param fin 
 * @return the AES encrypted byte[]
 */
private byte[] encryptFIN128AES(String fin) {

    SecretKeySpec sks = null;

    try {
        sks = new SecretKeySpec(generateKey("Test1".toCharArray(), "Test2".getBytes()).getEncoded(),"AES");
    } catch (Exception e) {
        Log.e("encryptFIN128AES", "AES key generation error");
    }

    // Encode the original data with AES
    byte[] encodedBytes = null;
    try {
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, sks);
        encodedBytes = c.doFinal(fin.getBytes());
    } catch (Exception e) {
        Log.e("encryptFIN128AES", "AES encryption error");
    }

    return encodedBytes;

}


/**
 * Decrypts a string with AES (128 bit key)
 * @param encodedBytes
 * @return the decrypted String
 */
private String decryptFIN128AES(byte[] encodedBytes) {

    SecretKeySpec sks = null;

    try {
        sks = new SecretKeySpec(generateKey("Test1".toCharArray(), "Test2".getBytes()).getEncoded(),"AES");
    } catch (Exception e) {
        Log.e("decryptFIN128AES", "AES key generation error");
    }

    // Decode the encoded data with AES
    byte[] decodedBytes = null;
    try {
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, sks);
        decodedBytes = c.doFinal(encodedBytes);
    } catch (Exception e) {
        Log.e("decryptFIN128AES", "AES decryption error");
    }

    return Base64.encodeToString(decodedBytes, Base64.DEFAULT);
}


public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt)
        throws NoSuchAlgorithmException, InvalidKeySpecException {

    final int iterations = 1000;

    // Generate a 256-bit key
    final int outputKeyLength = 128;

    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
    SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
    return secretKey;
}

Resultado:

E/AES_Test: b = cGxz

**

[EDIT] Modifiquei meu código, mas agora existe uma NullPointerException

**

/**
     * Encrypts a string with AES (128 bit key)
     * @param fin
     * @return the AES encrypted string
     */
    private byte[] encryptFIN128AES(String fin) {

        SecretKeySpec sks = null;

        try {
            sks = new SecretKeySpec(generateKey(PASSPHRASE, SALT.getBytes(StandardCharsets.UTF_8)).getEncoded(), "AES");
        } catch (Exception e) {
            Log.e("encryptFIN128AES", "AES key generation error");
        }

        // Encode the original data with AES
        byte[] encodedBytes = null;
        try {
            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
            c.init(Cipher.ENCRYPT_MODE, sks);
            encodedBytes = c.doFinal(fin.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            Log.e("encryptFIN128AES", "AES encryption error");
        }

        return encodedBytes;

    }


    /**
     * Decrypts a string with AES (128 bit key)
     * @param encodedBytes
     * @return the decrypted String
     */
    private String decryptFIN128AES(byte[] encodedBytes) {

        SecretKeySpec sks = null;

        try {
            sks = new SecretKeySpec(generateKey(PASSPHRASE, SALT.getBytes(StandardCharsets.UTF_8)).getEncoded(), "AES");
        } catch (Exception e) {
            Log.e("decryptFIN128AES", "AES key generation error");
        }

        // Decode the encoded data with AES
        byte[] decodedBytes = null;
        try {
            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
            c.init(Cipher.DECRYPT_MODE, sks);
            decodedBytes = c.doFinal(encodedBytes);
        } catch (Exception e) {
            Log.e("decryptFIN128AES", "AES decryption error");
        }

        //return Base64.encodeToString(decodedBytes, Base64.DEFAULT);
        return new String(decodedBytes, StandardCharsets.UTF_8);
    }

// generateKey(char[] passphraseOrPin, byte[] salt) remains the same

Erro:

E/decryptFIN128AES: AES decryption error
E/AndroidRuntime: FATAL EXCEPTION: Thread-176
                  Process: testapp.ttyi.nfcapp, PID: 2920
                  java.lang.NullPointerException: Attempt to get length of null array
                      at java.lang.String.<init>(String.java:371)
                      at testapp.ttyi.nfcapp.DisplayQRActivity.decryptFIN128AES(DisplayQRActivity.java:254)
                      at testapp.ttyi.nfcapp.DisplayQRActivity.access$100(DisplayQRActivity.java:29)
                      at testapp.ttyi.nfcapp.DisplayQRActivity$1.run(DisplayQRActivity.java:77)
                      at java.lang.Thread.run(Thread.java:818)

**

[EDIT2] Resolvido (mas nenhum modo de preenchimento / criptografia é permitido)

**

Consegui resolver o problema. (Decodifica para "pls") usando a solução de Codo dereturn new String(decodedBytes, StandardCharsets.UTF_8);

Embora só funcione quando o algoritmo usado é:Cipher c = Cipher.getInstance("AES");

Quando eu colocoCipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); A "NullPointerException", como visto acima, acontecerá. Minha observação mostra que durante a descriptografia:

 try {
                Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
                c.init(Cipher.DECRYPT_MODE, sks);
                decodedBytes = c.doFinal(encodedBytes);
            } catch (Exception e) {
                Log.e("decryptFIN128AES", "AES decryption error");
            }

algo falhará e sempre será impresso:

E/decryptFIN128AES: AES decryption error

E, assim, o NullPointerException ocorrerá comodecodedBytes é sempre iniciado como NULL.

questionAnswers(3)

yourAnswerToTheQuestion