Search code examples
javaandroidencryption3des

Wrong cipher text length when using 3DESede with PKS5 padding of javax.crypto


I am using the following code in my android application to encrypt a string in Triple DES using the Encrypted Code Book (ECB) mode with three independent keys (aka 3DESede), which are provided as a 24 byte sized key array. Therefore I use the Java Crypto API. This works pretty well, but if I encrypt an eight character string I get a 16 byte cipher text, which should not happen as 3DES operates on chunks of 64 bit (resp. 8 byte). Same holds for the PKCS5 padding as this also operates on chunks of 64 bit. So my question is what causes this problem?

private static byte[] encryptText(String plaintext, byte[] keyBytes) throws Exception {
    // Get plaintext as ASCII byte array
    final byte[] plainBytes;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        plainBytes = plaintext.getBytes(StandardCharsets.US_ASCII);
    } else {
        plainBytes = plaintext.getBytes("US-ASCII");
    }

    // Generate triple DES key from byte array
    final DESedeKeySpec keySpec = new DESedeKeySpec(keyBytes);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
    SecretKey key = keyFactory.generateSecret(keySpec);

    // Setup the cipher
    final Cipher c3des = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    c3des.init(Cipher.ENCRYPT_MODE, key);

    // Return ciphertext
    return c3des.doFinal(plainBytes);
}

Solution

  • PKCS5Padding adds 1-8 bytes of padding when used with DES. If you encrypt 8 bytes you will get 8 additional bytes of padding to get to an even number of blocks.

    If you used Cipher.getInstance("DES/ECB/NoPadding") and encrypted 8 bytes, you will get 8 bytes of cipher text.