Sorry to bring this up again, but unfortunately my solution only works for
strings that are exactly 16 characters long. I'm not sure what I'm doing
wrong. This seems like it should be so simple...
public class CryptoTest {
private static final String appkey = "sA1FGmFsXUHwPXrJOyWYfA==";
private static final String value16 = "ABCDEFGHIJKLMNOP";
private static final String value8 = "ABCDEFGH";
private static final String value13a = "4007000000027";
private static final String value13b = "4007000000027 ";
private static final String value13c = "4007000000027...";
private static final String value13d = "4007000000027XXX";
public static void main(String[] args) {
doIt(value8);
doIt(value16);
doIt(value13a);
doIt(value13b);
doIt(value13c);
doIt(value13d);
}
private static void doIt(String value) {
System.out.println("-----------");
System.out.println("Original Value: "+value);
System.out.println("Original Value length: "+value.length());
// Setup
AesCipherService cipherService = new AesCipherService();
byte[] bytes = Base64.decode(appkey.getBytes());
try {
// 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
byte[] decoded = Base64.decode(result1.getBytes());
System.out.println("Decoded length: "+decoded.length);
System.out.println("Decoded: "+new SimpleByteSource(decoded).toString());
ByteSource decrypted = cipherService.decrypt(decoded, bytes);
System.out.println("Decrypted: "+new
SimpleByteSource(Base64.decode(decrypted.getBytes())).toString());
} catch (CryptoException e) {
e.printStackTrace();
}
}
}
This produces the following output:
-----------
Original Value: ABCDEFGH
Original Value length: 8
Encrypted: DARMjklfVRyLoD1irf0apGStAymsKOEHR1/muvhwbag=
Encrypted length: 44
Decoded length: 32
Decoded: DARMjklfVRyLoD1irf0apGStAymsKOEHR1/muvhwbag=
Decrypted: ABCDEFGH
-----------
Original Value: ABCDEFGHIJKLMNOP
Original Value length: 16
Encrypted: 9ODpJ68Krm7PcjlvD7MVjmBefjijw6BTV1DWtt2mfqJxn6wccIRrs6hvV1/CWycr
Encrypted length: 64
Decoded length: 48
Decoded: 9ODpJ68Krm7PcjlvD7MVjmBefjijw6BTV1DWtt2mfqJxn6wccIRrs6hvV1/CWycr
Decrypted: ABCDEFGHIJKLMNOP
-----------
Original Value: 4007000000027
Original Value length: 13
Encrypted: g5KGBx/79z6e/CapGmVhAbApmxpZ+v2+xcChw+bQrrE=
Encrypted length: 44
Decoded length: 32
Decoded: g5KGBx/79z6e/CapGmVhAbApmxpZ+v2+xcChw+bQrrE=
Decrypted: 400700000002AA==
-----------
Original Value: 4007000000027
Original Value length: 16
Encrypted: qtX3ct7uVg11kZqwGiPK0JB5wi5E40+I3kHpk3bOcHu3n/cxPd/b5q8dE0CRM7aX
Encrypted length: 64
Decoded length: 48
Decoded: qtX3ct7uVg11kZqwGiPK0JB5wi5E40+I3kHpk3bOcHu3n/cxPd/b5q8dE0CRM7aX
Decrypted: 400700000002AA==
-----------
Original Value: 4007000000027...
Original Value length: 16
Encrypted: 6RdBKnJDxOMVjvQoMu6UHfZ/ZOLoEVB+lBfoBySKSax+Ivv49fA3zUhIos4LWsXG
Encrypted length: 64
Decoded length: 48
Decoded: 6RdBKnJDxOMVjvQoMu6UHfZ/ZOLoEVB+lBfoBySKSax+Ivv49fA3zUhIos4LWsXG
Decrypted: 400700000002AA==
-----------
Original Value: 4007000000027XXX
Original Value length: 16
Encrypted: heR4cKiGBuXOUWqzsTS+oy3X0ygVcc8z2iqUv+rSf79sozT00csoepRDklSXx36+
Encrypted length: 64
Decoded length: 48
Decoded: heR4cKiGBuXOUWqzsTS+oy3X0ygVcc8z2iqUv+rSf79sozT00csoepRDklSXx36+
Decrypted: 4007000000027XXX
The weird thing is that strings of numbers or letters that are 8 or 16
characters long work. But if the string is 13 characters long and padded
with spaces or periods to make it 16 long, it still doesn't work right.
What's going on? I'm feeling quite stupid right now, hopefully someone can
clear it all up for me.
Thanks!
Tauren
On Tue, Apr 5, 2011 at 5:41 AM, Tauren Mills <[email protected]> wrote:
> Never mind, and sorry for the noise. I should stop working all night and
> get some sleep.
>
> I had forgotten to do a Base64.decode() before decrypting. Once I added
> that, it works a whole lot better!
>
> Tauren
>
>
> On Tue, Apr 5, 2011 at 4:53 AM, Tauren Mills <[email protected]> wrote:
>
>> 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
>>
>>
>>
>