Home > Archive > Java Security > July 2006 > Help, I am having difficulty implementing JCE/AES
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Help, I am having difficulty implementing JCE/AES
|
|
|
| I am trying to write a routine that will encrypt/decrypt a input string but
am having problems getting the decryption to work.
Using the following code to encrypt the string 1234567890123456 I get the
result [B@1ff7a1e
Yet when I try to decrypt the string I get the foillowing error message
mode [decrypt] data [[B@1ff7a1e]
decryption mode
Error Given final block not properly padded
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA12275)
at javax.crypto.Cipher.doFinal(DashoA12275)
at testaes.Main.<init>(Main.java:75)
at testaes.Main.main(Main.java:93)
Can anyone tell me where I am going wrong?
In particular I have tried to implement the padding, described in
http://www.faqs.org/rfcs/rfc2315.html, at line 63
which is
> 2. Some content-encryption algorithms assume the
> input length is a multiple of k octets, where k > 1, and
> let the application define a method for handling inputs
> whose lengths are not a multiple of k octets. For such
> algorithms, the method shall be to pad the input at the
> trailing end with k - (l mod k) octets all having value k -
> (l mod k), where l is the length of the input. In other
> words, the input is padded at the trailing end with one of
> the following strings:
>
> 01 -- if l mod k = k-1
> 02 02 -- if l mod k = k-2
> .
> .
> .
> k k ... k k -- if l mod k = 0
>
> The padding can be removed unambiguously since all input is
> padded and no padding string is a suffix of another. This
> padding method is well-defined if and only if k < 256;
> methods for larger k are an open issue for further study.
package testaes;
import com.sun.org.apache.xerces.internal.impl.dv.xs.DecimalDV;
import java.security.*;
import java.text.DecimalFormat;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
public class Main
{
public Main(String[] args)
{
try
{
// get key generator using the default provider
Cipher AesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// keyBytes is the key used to encrypt/decrypt
byte[] keyBytes = {
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb,
(byte)0xbb
};
SecretKeySpec KeySpec = new SecretKeySpec(keyBytes, "AES");
// CipherText is the encrypted PlainText
byte[] CipherText = { (byte)0x00 };
String PlainText = args[1];
if (args[0].equalsIgnoreCase("encrypt"))
// encrypt args[1]
{
System.out.println("encryption mode");
AesCipher.init(Cipher.ENCRYPT_MODE, KeySpec);
}
else if (args[0].equalsIgnoreCase("decrypt"))
// decrypt args[1]
{
System.out.println("decryption mode");
AesCipher.init(Cipher.ENCRYPT_MODE, KeySpec);
AesCipher.init(Cipher.DECRYPT_MODE, KeySpec, AesCipher.getParameters());
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
byteArray.write(PlainText.getBytes());
for (int loop = ((PlainText.length() == 16) ? 16 : (16 -
(PlainText.length() % 16))); loop > 0; loop--)
{
byteArray.write((byte)(16 - (PlainText.length() % 16)));
}
PlainText = byteArray.toString();
}
else
// unknown mode
{
System.out.println("Unknown operation mode");
return;
}
CipherText = AesCipher.doFinal(PlainText.getBytes());
System.out.println("The encrypted text is [" + CipherText + "]");
}
catch (Throwable e)
{
System.out.println("Error " + e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args)
{
try
{
System.out.println("mode [" + args[0] + "] data [" + args[1] + "]");
Main testAES = new Main(args);
}
catch (Throwable e)
{
System.out.println("Error " + e.getMessage());
e.printStackTrace();
}
}
}
| |
|
| <snip>
> // keyBytes is the key used to encrypt/decrypt
> byte[] keyBytes = {
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb,
> (byte)0xbb
> };
> SecretKeySpec KeySpec = new
> SecretKeySpec(keyBytes, "AES");
<snip>
I am also finding that even if I change the bytes in the keyBytes array,
this has no affect on the final encrypted output?
TIA,
Pep.
| |
| Mike Amling 2006-07-07, 7:01 pm |
| Pep wrote:
> I am trying to write a routine that will encrypt/decrypt a input string but
> am having problems getting the decryption to work.
>
> Using the following code to encrypt the string 1234567890123456 I get the
> result [B@1ff7a1e
>
> Yet when I try to decrypt the string I get the foillowing error message
>
> mode [decrypt] data [[B@1ff7a1e]
> decryption mode
> Error Given final block not properly padded
> javax.crypto.BadPaddingException: Given final block not properly padded
> at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
> at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
> at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA12275)
> at javax.crypto.Cipher.doFinal(DashoA12275)
> at testaes.Main.<init>(Main.java:75)
> at testaes.Main.main(Main.java:93)
>
> Can anyone tell me where I am going wrong?
>
>
> // CipherText is the encrypted PlainText
> byte[] CipherText = { (byte)0x00 };
> CipherText = AesCipher.doFinal(PlainText.getBytes());
>
> System.out.println("The encrypted text is [" + CipherText + "]");
You know, of course, that your System.out.println prints
CipherText.toString(). But did you know that toString() for an array is
just the default toString() for Object? If you want to print the
contents of the array rather than the array's class name and hashCode,
you'll have to do some work.
--Mike Amling
| |
|
| Mike Amling wrote:
> Pep wrote:
>
> You know, of course, that your System.out.println prints
> CipherText.toString(). But did you know that toString() for an array is
> just the default toString() for Object? If you want to print the
> contents of the array rather than the array's class name and hashCode,
> you'll have to do some work.
>
> --Mike Amling
Yep I realised that and fixed it accordingly, I think it was just
frustration trying to get JCE working in my environment.
I have that the encryption/decryption solved now for the java implementation
but now have a problem with the encrypted packets from the C++ client and
also sending them back but I'll do that ini anothe rthread now that I have
the program working(ish).
Cheers,
Pep.
|
|
|
|
|