Search code examples
androidaesencryption-symmetricencryption-asymmetricandroid-security

Generate 32 character AES string with 16 character initialization vector in android


I am using below class for generating AES 256 key, initialization vector, encryption and decryption in android. There are few issues, that I am facing

1) When I call getInitializationVector() it return 24 characters instead of 16.(ex: WoiUFsQpizjG705OXja1Jw==)
2) When I call generateKey(), it returns 44 characters instead of 32.(ex:tEf+dcrzI4x+kSMS8UZxjwziGySMMkDxO0aVgsj0oBs=)
3) The below class is symmetric approach, How to make it asymmetric.

You can see textKey and testIV for default ones. But I am unable to create it. I have searched in stack overflow for solutions but, All are returning me same length text. Does anyone know how to do this? Am I doing wrong? Thanks for your valuable time in advance.

public class CryptoDataHandler {

    //32 characters
    String testKey = "82a645babc5cd41c9a2cb4d0d3ba17ad";
    //16 characters
    String testIV = "acf30ad32b693849";

    String edType = "AES";
    String chiperInstanceType = "AES/CBC/PKCS5PADDING";

    private static CryptoDataHandler instance = null;

    public static CryptoDataHandler getInstance() {

        if (instance == null) {
            Security.setProperty("crypto.policy", "unlimited");
            instance = new CryptoDataHandler();
        }
        return instance;
    }

    public String encrypt(String message) throws NoSuchAlgorithmException,
            NoSuchPaddingException, IllegalBlockSizeException,
            BadPaddingException, InvalidKeyException,
            UnsupportedEncodingException, InvalidAlgorithmParameterException {

        byte[] srcBuff = message.getBytes(StandardCharsets.UTF_8);
        //here using substring because AES takes only 16 or 24 or 32 byte of key
        SecretKeySpec skeySpec = new
                SecretKeySpec(testKey.substring(0, 32).getBytes(), edType);
        IvParameterSpec ivSpec = new
                IvParameterSpec(testIV.substring(0, 16).getBytes());
        Cipher ecipher = Cipher.getInstance(chiperInstanceType);
        ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
        byte[] dstBuff = ecipher.doFinal(srcBuff);
        return Base64.encodeToString(dstBuff, Base64.DEFAULT);
    }

    public String decrypt(String encrypted) throws NoSuchAlgorithmException,
            NoSuchPaddingException, InvalidKeyException,
            InvalidAlgorithmParameterException, IllegalBlockSizeException,
            BadPaddingException, UnsupportedEncodingException {

        SecretKeySpec skeySpec = new
                SecretKeySpec(testKey.substring(0, 32).getBytes(), edType);
        IvParameterSpec ivSpec = new
                IvParameterSpec(testIV.substring(0, 16).getBytes());
        Cipher ecipher = Cipher.getInstance(chiperInstanceType);
        ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
        byte[] raw = Base64.decode(encrypted, Base64.DEFAULT);
        byte[] originalBytes = ecipher.doFinal(raw);
        return new String(originalBytes, StandardCharsets.UTF_8);
    }

    public String generateKey() {

        try {
            Key key;
            SecureRandom rand = new SecureRandom();
            KeyGenerator generator = KeyGenerator.getInstance(edType);
            generator.init(256, rand);
            key = generator.generateKey();
            return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return null;
    }


    public String getInitializationVector() {
        byte[] IV = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(IV);
        return Base64.encodeToString(IV, Base64.DEFAULT);
    }
}


Solution

  • Well, I have found a solution. Posting it here. If it's helpful for someone else.

    I just modified my KEY and IV generation method, for exact 32 and 16 characters. And I have tested the encryption and decryption and it's working fine.

    public String generateKey() {
    
        try {
            Key key;
            SecureRandom rand = new SecureRandom();
            KeyGenerator generator = KeyGenerator.getInstance(edType);
            generator.init(256, rand);
            key = generator.generateKey();
            return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT).subString(0,32);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    
        return null;
    }
    
    
    public String getInitializationVector() {
        byte[] IV = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(IV);
        return Base64.encodeToString(IV, Base64.DEFAULT).subString(0,16);
    }