Java AES without padding
Solution 1
See my comment. Sorry I probably should have taken a closer look the first time.
- Change
"AES"
to"AES/CBC/NoPadding"
- Change
decryptor.init(Cipher.DECRYPT_MODE, skeySpec);
todecryptor.init(Cipher.DECRYPT_MODE, skeySpec, encryptor.gerParameters());
To encrypt only 16 bytes of data, fixed length, using a method that requires no initialization vector to be saved, Change "AES"
to "AES/ECB/NoPadding"
I pick ECB because that is the default.
If you need to encrypt more than 16 bytes, consider using something other than ECB, which suffers a certain repetition detection flaw
In this bitmap example, this image has repeated white blocks, so you can deduce the outline of the image simply by looking for where the blocks become different.
If you are only encrypting one block, it doesn't really matter though, only if you are encrypting multiple blocks that are combined does ECB become revealing.
Related: https://security.stackexchange.com/questions/15740/what-are-the-variables-of-aes
Solution 2
Agree with @rossum, but there's more to it:
CTR mode needs an initialisation vector (IV). This is a "counter" (which is what "CTR" refers to). If you can store the IV separately (it doesn't need to be protected) that would work. You'll need the same IV value when you decrypt the data.
If you don't want to store the IV and you can guarantee that no two values will be encrypted with the same key, it's fine to use a fixed IV (even an array of 0s).
The above is very important because encrypting more than one message with the same key/IV combination destroys security. See the Initialization vector (IV) section in this Wikipedia article: http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
An AES CTR implementation of your code might be:
SecretKeySpec skeySpec = new SecretKeySpec(getCryptoKeyByteArray(length=16));
Cipher encryptor = Cipher.getInstance("AES/CTR/NoPadding");
// Initialisation vector:
byte[] iv = new byte[encryptor.getBlockSize()];
SecureRandom.getInstance("SHA1PRNG").nextBytes(iv); // If storing separately
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
encryptor.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encrypted = encryptor.doFinal(plain);
Solution 3
CTR mode does not require padding: "AES/CTR/NoPadding"
.
700 Software
Join 700.social ! A happy medium between Facebook and Gab. :) The name is too long but the domain looks good. Also, Software Development / Consulting (423) 802-8971 700software.com old username: George Bailey (but now I use my real name) http://www.google.com/images?q=George+Bailey
Updated on July 10, 2022Comments
-
700 Software almost 2 years
What are some of the simplest ways to AES encrypt and decrypt a 16 byte array without the automatic padding? I have found solutions that use external libraries, but I want to avoid that if possible.
My current code is
SecretKeySpec skeySpec = new SecretKeySpec(getCryptoKeyByteArray(length=16)); // 128 bits Cipher encryptor = Cipher.getInstance("AES"); encryptor.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = encryptor.doFinal(plain);
How can I prevent the padding? The
plain
data is always fixed length and includes its own padding. How can I allowplain
to be 16 bytes without causingencrypted
to become 32 bytes?