Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is AES/ CBC/ PKCS5Padding encryption decryption algorithm and SHA-1 hashing algorithm avaible in all type of Android devices

I had tried to run the following AES/ CBC/ PKCS5Padding encryption and decryption code, with SHA-1 as key generation, in Nexus 5. It works very well so far.

However, my only concern is, Is AES/ CBC/ PKCS5Padding encryption decryption algorithm and SHA-1 hashing algorithm available in all type of Android devices?

Is there any chance that the following code will fail to run on certain Android devices? If so, is there any fall back plan?

AES/ CBC/ PKCS5Padding

// http://stackoverflow.com/questions/3451670/java-aes-and-using-my-own-key
public static byte[] generateKey(String key) throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] binary = key.getBytes("UTF-8");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    binary = sha.digest(binary);
    // Use only first 128 bit.
    binary = Arrays.copyOf(binary, 16);
    return binary;
}

// http://stackoverflow.com/questions/17322002/what-causes-the-error-java-security-invalidkeyexception-parameters-missing
public static String encrypt(byte[] key, String value) throws GeneralSecurityException {
    // Argument validation.
    if (key.length != 16) {
        throw new IllegalArgumentException("Invalid key size.");
    }

    // Setup AES tool.
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

    // Do the job with AES tool.
    byte[] original = value.getBytes(Charset.forName("UTF-8"));
    byte[] binary = cipher.doFinal(original);
    return Base64.encodeToString(binary, Base64.DEFAULT);
}

// // http://stackoverflow.com/questions/17322002/what-causes-the-error-java-security-invalidkeyexception-parameters-missing
public static String decrypt(byte[] key, String encrypted) throws GeneralSecurityException {
    // Argument validation.
    if (key.length != 16) {
        throw new IllegalArgumentException("Invalid key size.");
    }

    // Setup AES tool.
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

    // Do the job with AES tool.
    byte[] binary = Base64.decode(encrypted, Base64.DEFAULT);
    byte[] original = cipher.doFinal(binary);
    return new String(original, Charset.forName("UTF-8"));
}

Usage

byte[] key = generateKey("my secret key");
String ciphertext = encrypt(key, "my plain content");
String plainContent = decrypt(key, ciphertext);
like image 923
Cheok Yan Cheng Avatar asked Apr 11 '15 05:04

Cheok Yan Cheng


People also ask

Does Java support the AES/cbc/pkcs5padding algorithm?

The Java API's have contained the "AES/CBC/PKCS5Padding" since version 1.4. As for "SHA-1", that's an even older algorithm, which has been supported since time began. Beware not to use "PKCS7Padding" instead. Java uses "PKCS5Padding" as replacement, "PKCS7Padding" support may be sketchy even if it means the same thing.

What is AES encryption in Java with CBC mode?

Since AES Encryption is an Symmetric algorithm we will be using the same Secret Key for both Encryption as well as Decryption. In this article, we will be discussing about AES (A dvanced E ncryption S tandard ) Symmetric Encryption algorithm in Java with CBC mode ( C ipher B lock C haining). What is AES Encryption?

What is the best encryption algorithm for Java?

But most experts refer to data encryption as the best method and currently, Java AES is an advanced solution available for ciphering. New algorithms are replacing the old values of DES towards the AES.

What is AES encoding algorithm?

For encoding, the AES algorithm is repetitive in nature and supports 128, 192, and 256 bits. It functions like the below pattern. The choice of the key is required to future-proof the application. private static final String SALT = "ssshhhhhhhhhhh!!!!"; If there is no proper padding to the block, then the system shows errors of the password.


2 Answers

This isn't answering your question directly, but...

cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

Do not use this construct! It will break any security you think you're getting!

This invocation initialises your cipher object with an all-zeros initialisation vector. This is a very very very bad thing, especially with CBC: CBC is quite malleable, and doesn't do any integrity-protection. Make sure you generate your IV using SecureRandom or similar, and preferably use GCM or CCM.

like image 22
Justin King-Lacroix Avatar answered Oct 01 '22 19:10

Justin King-Lacroix


No, it's unlikely to the extreme that it will fail. The Android API has been derived from the Java API's. The Java API's have contained the "AES/CBC/PKCS5Padding" since version 1.4.

As for "SHA-1", that's an even older algorithm, which has been supported since time began.

Beware not to use "PKCS7Padding" instead. Java uses "PKCS5Padding" as replacement, "PKCS7Padding" support may be sketchy even if it means the same thing.


Note that you should be using password based encryption (PBE) instead of AES/CBC and SHA-1. Especially using SHA-1 as key derivation method is particularly dangerous as you don't use a salt or work factor as a good Password Based Key Derivation Function such as PBKDF2 should. Basically only do this if you know your password contains enough entropy.

Using an all zero IV for the same key is worse though (as already indicated in the comments). It lets attackers find repeats of (the starting blocks of) plaintext input. Authenticated encryption (e.g. using HMAC-SHA-1) is always recommended and more or less required for transport mode encryption (as opposed to in-place encryption where plaintext/padding oracle attacks are not possible).

like image 178
Maarten Bodewes Avatar answered Oct 01 '22 20:10

Maarten Bodewes