Q:

AES/CBC/NoPadding and IllegalBlockSizeException - Custom padding handling

UPDATE: I removed another issue in my code to make the question more precise.
I need to encrypt a String with variable length with AES/CBC/NoPadding but I'm getting an IllegalBlockSizeException.
I have to use NoPadding because the input should have the same length as the output even if the decryption fails. 
It shouldn't be possible to determine that it failed.
Before I used AES/CBC/PKCS5Padding without any problem but that is not an option. So my question is:
How do I add a custom padding to get a multiple of 16 byte or what possibly leads to the IllegalBlockSizeException (DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH)? I also read that ciphertext stealing is a way to do so. I would be grateful for an example.
Here's my current code:
private static final String KEY_TRANSFORMATION_ALGORITHM_SYM = "AES/CBC/NoPadding";

@NonNull
static String encryptMessage(@NonNull String plainMessage,
                             @NonNull SharedPreferences storage,
                             @Nullable Key aesKey,
                             @NonNull String charset) {
    if (aesKey == null) {
        throw new RuntimeException("AES key is null", null);
    }
    try {
        // Cipher can not be re-used on Android
        Cipher cipher = Cipher.getInstance(KEY_TRANSFORMATION_ALGORITHM_SYM);
        cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(getIV(storage, cipher, charset)));
        byte[] charsetEncryptedData = cipher.doFinal(plainMessage.getBytes(charset));
        return Base64.encodeToString(charsetEncryptedData, Base64.NO_WRAP);

    } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException | BadPaddingException | IllegalBlockSizeException | UnsupportedEncodingException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

@NonNull
static String decryptMessage(@NonNull String encryptedMessage,
                             @NonNull SharedPreferences storage,
                             @Nullable Key aesKey,
                             @NonNull String charset) {
    if (aesKey == null) {
        throw new RuntimeException("AES key is null", null);
    }
    try {
        //Cipher can not be re-used on Android
        Cipher cipher = Cipher.getInstance(KEY_TRANSFORMATION_ALGORITHM_SYM);
        cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(getIV(storage, cipher, charset)));

        byte[] decryptedData = Base64.decode(encryptedMessage.getBytes(charset), Base64.NO_WRAP);
        byte[] charsetEncryptedData = cipher.doFinal(decryptedData);
        return new String(charsetEncryptedData, charset);

    } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException | UnsupportedEncodingException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

A:

I solved my issue with the following code. I had to add a custom padding with spaces:
@NonNull
static String encryptMessage(@NonNull String plainMessage,
                             @NonNull SharedPreferences storage,
                             @Nullable Key aesKey,
                             @NonNull String charset) {
        //...
        // add spaces (custom padding) until the plainMessage.getBytes can be divided by 16 without rest --> this is the solution I was looking for
        while (plainMessage.getBytes().length % 16 != 0) {
            plainMessage += '\u0020';
        }
        //...
}

@NonNull
static String decryptMessage(@NonNull String encryptedMessage,
                             @NonNull SharedPreferences storage,
                             @Nullable Key aesKey,
                             @NonNull String charset) {
        //...
        // trim the String to get rid of the spaces
        return new String(charsetEncryptedData, charset).trim();
        //...
}

