I finally got around to testing out some crypto code and am having
CryptoExceptions thrown when decrypting. The problem seems to be with
padding. I was under the assumption that Shiro took care of all that for me.
If not, how do I solve this?
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.CryptoException;
import org.apache.shiro.util.ByteSource;
public class CryptoTest {
private static final String appkey = "sA1FGmFsXUHwPXrJOyWYfA==";
private static final String value16 = "ABCDEFGHIJKLMNOP";
private static final String value8 = "ABCDEFGH";
public static void main(String[] args) {
try {
doIt(value8);
} catch (CryptoException e) {
e.printStackTrace();
}
System.out.println("-----------");
try {
doIt(value16);
} catch (CryptoException e) {
e.printStackTrace();
}
}
private static void doIt(String value) throws CryptoException {
System.out.println("Value: "+value);
System.out.println("Value length: "+value.length());
// Setup
AesCipherService cipherService = new AesCipherService();
byte[] bytes = Base64.decode(appkey.getBytes());
// Encrypt value
ByteSource encrypted = cipherService.encrypt(value.getBytes(), bytes);
String result1 = encrypted.toBase64();
System.out.println("Encrypted: "+result1);
System.out.println("Encrypted length: "+result1.length());
// Decrypt result
ByteSource decrypted = cipherService.decrypt(result1.getBytes(), bytes);
String result2 = decrypted.toString();
System.out.println("Decrypted: "+result2);
System.out.println("Decrypted length: "+result2.length());
}
}
This produces the following output:
Value: ABCDEFGH
Value length: 8
Encrypted: +LZxy50cDjd8UFanLoNLa8yvw6ctNLRGJsY4BzDIM8s=
Encrypted length: 44
-----------
Value: ABCDEFGHIJKLMNOP
Value length: 16
Encrypted: fgc/8DUeyt7wQkO/TS3SNwaTOVU3swTMaMHMm3mQ05jge77vrXlrxQYNoqPey1wg
Encrypted length: 64
org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with
cipher instance [javax.crypto.Cipher@17386918].
at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:464)
at
org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:447)
at
org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:392)
at
org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:384)
at com.sprtz.test.CryptoTest.doIt(CryptoTest.java:61)
at com.sprtz.test.CryptoTest.main(CryptoTest.java:17)
Caused by: javax.crypto.IllegalBlockSizeException: Input length must be
multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at
org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:461)
... 5 more
org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with
cipher instance [javax.crypto.Cipher@787bb290].
at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:464)
at
org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:447)
at
org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:392)
at
org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:384)
at com.sprtz.test.CryptoTest.doIt(CryptoTest.java:61)
at com.sprtz.test.CryptoTest.main(CryptoTest.java:25)
Caused by: javax.crypto.BadPaddingException: Given final block not properly
padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at
org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:461)
... 5 more
The code seems fairly straight forward. Notice the exceptions are different
based on the length of the value to encrypt/decrypt.
I'm using 128bit AES since I don't have the extras installed. Any thoughts
on what I am doing wrong?
Thanks,
Tauren