Encrypt in Java and decrypt in Openssl (and vice versa)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Encrypt in Java and decrypt in Openssl (and vice versa)

uno wand
Hi all,

I've been pulling my hair for two days, trying to figure out why a msg
encrypted in Java
can not be decrypted with Openssl, and vice versa. It'd be very much
appreciated if
someone could give a hint.

Here's the Java code (apologize for that) (no exception handling):

  byte[] key; // get hard-coded key, 16 bytes
  SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); // or
"AES/CBC/PKCS5Padding", same result
  IvParameterSpec ivSpec = new IvParameterSpec("12345678".getBytes());

  // Encrypt
  Cipher cipher;
  cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
  String clearText = "This is a test";
  byte[] ciphertext = cipher.doFinal(cleartext.getBytes());
  // ...

  // Decrypt
  cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
  byte[] cleartext = cipher.doFinal(ciphertext);
  // ....

Here is the C code using Openssl (no error handling):

  unsigned char * key; // get hard-coded key, 16 bytes
  unsigned cha * iv; // get hard-coded iv, same as in Java, iv[0] = 49,
iv[1] = 50, ...
  EVP_CIPHER_CTX ctx;

  // Encrypt
  unsigned char outbuf[2048]; // should be enough for the work
  int outlen, tmplen;
  EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, _key, _iv, ENCRYPT);
  EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned char*)clearText, len);
  EVP_CipherFinal_ex(&ctx, outbuf + outlen, &tmplen);
  outlen += tmplen;
  // ...

  //Decrypt
  EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, _key, _iv, DECRYPT);
  EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned char*)cipherText, len);
  EVP_CipherFinal_ex(&ctx, outbuf + outlen, &tmplen);
  outlen += tmplen;
  // ...

The problem is, I can't decrypt what is encrypted in Java. And in Java, I
can't decrypt
what is encrypted from Openssl. Java reported a "Pad block corrypted" error.

I'd like to know which parameter did I set wrong? The key and IV are the
same,
hard-coded for the purpose of testing.

Thanks in advance for any help.

uw

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today - it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Encrypt in Java and decrypt in Openssl (and vice versa)

Girish Venkatachalam
You should take care that the key and IV are indeed
same. What I mean by that is that in the C and Java
code you should hardcode the actual hex values and it
should have the exact length. For instance DES
requires  8 byte key and you should hardcode something
like this.

unsigned char key[8] =
{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xff};

Similarly for IV. Make sure you do the right thing for
Java also.

And the last block will not be decrypted correctly
unless you take care to do proper PKCS padding. So
don't worry about it. Typical block size is 8 bytes,
so first you have to make sure that you get the
correct encrypted output.

Verify that against the openssl enc command. Print
your encrypted output using "%02X" format and try this
on the command line.
echo -n "something"|openssl aes-128-cbc -K <> -iv
<>|od -x

od -x prints differently from your hex output as words
are reversed but you can easily see the
correspondence.

Hope this helps.

regards,
Girish

--- uno wand <[hidden email]> wrote:

> Hi all,
>
> I've been pulling my hair for two days, trying to
> figure out why a msg
> encrypted in Java
> can not be decrypted with Openssl, and vice versa.
> It'd be very much
> appreciated if
> someone could give a hint.
>
> Here's the Java code (apologize for that) (no
> exception handling):
>
>   byte[] key; // get hard-coded key, 16 bytes
>   SecretKeySpec skeySpec = new SecretKeySpec(key,
> "AES"); // or
> "AES/CBC/PKCS5Padding", same result
>   IvParameterSpec ivSpec = new
> IvParameterSpec("12345678".getBytes());
>
>   // Encrypt
>   Cipher cipher;
>   cipher.init(Cipher.ENCRYPT_MODE, skeySpec,
> ivSpec);
>   String clearText = "This is a test";
>   byte[] ciphertext =
> cipher.doFinal(cleartext.getBytes());
>   // ...
>
>   // Decrypt
>   cipher.init(Cipher.DECRYPT_MODE, skeySpec,
> ivSpec);
>   byte[] cleartext = cipher.doFinal(ciphertext);
>   // ....
>
> Here is the C code using Openssl (no error
> handling):
>
>   unsigned char * key; // get hard-coded key, 16
> bytes
>   unsigned cha * iv; // get hard-coded iv, same as
> in Java, iv[0] = 49,
> iv[1] = 50, ...
>   EVP_CIPHER_CTX ctx;
>
>   // Encrypt
>   unsigned char outbuf[2048]; // should be enough
> for the work
>   int outlen, tmplen;
>   EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
> _key, _iv, ENCRYPT);
>   EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned
> char*)clearText, len);
>   EVP_CipherFinal_ex(&ctx, outbuf + outlen,
> &tmplen);
>   outlen += tmplen;
>   // ...
>
>   //Decrypt
>   EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
> _key, _iv, DECRYPT);
>   EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned
> char*)cipherText, len);
>   EVP_CipherFinal_ex(&ctx, outbuf + outlen,
> &tmplen);
>   outlen += tmplen;
>   // ...
>
> The problem is, I can't decrypt what is encrypted in
> Java. And in Java, I
> can't decrypt
> what is encrypted from Openssl. Java reported a "Pad
> block corrypted" error.
>
> I'd like to know which parameter did I set wrong?
> The key and IV are the
> same,
> hard-coded for the purpose of testing.
>
> Thanks in advance for any help.
>
> uw
>
>
_________________________________________________________________
> Express yourself instantly with MSN Messenger!
> Download today - it's FREE!
>
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
>
>
______________________________________________________________________
> OpenSSL Project                                
> http://www.openssl.org
> User Support Mailing List                  
> [hidden email]
> Automated List Manager                          
> [hidden email]
>


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Encrypt in Java and decrypt in Openssl (and vice versa)

uno wand
Thanks for replying. I have been verifying, and re-verifying that my key and
IV
are in fact the same in both C and Java.  The hex printout of the key and IV
are exactly the same.

Original Text: "This is a test"

The hex print of Java cipher text is :

740A5DBD288340D7AC8F9F20587B7F4D

And trying the command you gave, here is the result:

uno@neo:~$ echo -n "This is a test" |openssl enc -aes-128-cbc -K
9d320b14da2485e6dfa1a8eb5f2bd326 -iv 0102030405060708 |od -t x2
0000000 1e8b b7de 5736 ea6f bf54 1e6f d4d4 4a53
0000020

The value for -K is the hex printout of the key I used, both in Java and C.
the value of -iv is also the hex printout.

The result looks quite different, isn't it? Am I missing something?

Thanks

uw

>From: Girish Venkatachalam <[hidden email]>
>
>You should take care that the key and IV are indeed
>same. What I mean by that is that in the C and Java
>code you should hardcode the actual hex values and it
>should have the exact length. For instance DES
>requires  8 byte key and you should hardcode something
>like this.
>
>unsigned char key[8] =
>{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xff};
>
>Similarly for IV. Make sure you do the right thing for
>Java also.
>
>And the last block will not be decrypted correctly
>unless you take care to do proper PKCS padding. So
>don't worry about it. Typical block size is 8 bytes,
>so first you have to make sure that you get the
>correct encrypted output.
>
>Verify that against the openssl enc command. Print
>your encrypted output using "%02X" format and try this
>on the command line.
>echo -n "something"|openssl aes-128-cbc -K <> -iv
><>|od -x
>
>od -x prints differently from your hex output as words
>are reversed but you can easily see the
>correspondence.
>
>Hope this helps.
>
>regards,
>Girish
>

_________________________________________________________________
Is your PC infected? Get a FREE online computer virus scan from McAfee®
Security. http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Encrypt in Java and decrypt in Openssl (and vice versa)

Dr. Stephen Henson
On Sat, Mar 11, 2006, uno wand wrote:

> Thanks for replying. I have been verifying, and re-verifying that my key
> and IV
> are in fact the same in both C and Java.  The hex printout of the key and IV
> are exactly the same.
>
> Original Text: "This is a test"
>
> The hex print of Java cipher text is :
>
> 740A5DBD288340D7AC8F9F20587B7F4D
>
> And trying the command you gave, here is the result:
>
> uno@neo:~$ echo -n "This is a test" |openssl enc -aes-128-cbc -K
> 9d320b14da2485e6dfa1a8eb5f2bd326 -iv 0102030405060708 |od -t x2
> 0000000 1e8b b7de 5736 ea6f bf54 1e6f d4d4 4a53
> 0000020
>
> The value for -K is the hex printout of the key I used, both in Java and C.
> the value of -iv is also the hex printout.
>
> The result looks quite different, isn't it? Am I missing something?
>

The block size of AES is 128 bits, you therefore need 16 characters or 32 hex
digits in the IV.

Steve.
--
Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage
OpenSSL project core developer and freelance consultant.
Funding needed! Details on homepage.
Homepage: http://www.drh-consultancy.demon.co.uk
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Encrypt in Java and decrypt in Openssl (and vice versa)

uno wand
>From: "Dr. Stephen Henson" <[hidden email]>
>
>The block size of AES is 128 bits, you therefore need 16 characters or 32
>hex
>digits in the IV.
>
>Steve.
>--

Thanks for the reply, I figured that out earlier too, by re-reading the
documentation
I have on hand. I always had the impression that if I do in Java

  Cipher cipher = Cipher.getInstance("AES");

it is equivalent to

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

That is obviously not true. After changing that, that helped a bit.

And after changing the IV to 16 bytes, I got something going, . Now, IV is
hard-coded to

  unsigned char * _iv[16];
  for (int i = 0; i < 16; i++)
      _iv[i] = '1' + i;

in both Java and C.

But it's still not totally right.

Encrypted msg (just text) from Java is decoded "almost" correctly. The msg
consists of multiple lines of text string, but after decrypting it, the
first line
always get screwed up and I get garbage. All other lines are decrypted
correctly.

But encrypted msg from Openssl is decrypted in Java "half correct", meaning
that if I have 8 lines of string, I get about 4 lines correct, the others
are
garbage. And the order is indeterminate, the first line is always screwed
up,
the second line is ok sometimes, not ok other times. Same for the other
lines.

I really have no clue why it's like that. I mean, you either decrypt the
whole
message correctly, or you don't. I really don't understand how did I get
"partially correct" decryption :(

thanks for all.

uw

_________________________________________________________________
Don’t just search. Find. Check out the new MSN Search!
http://search.msn.click-url.com/go/onm00200636ave/direct/01/

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Encrypt in Java and decrypt in Openssl (and vice versa)

Dominique LOHEZ
uno wand wrote:

>> From: "Dr. Stephen Henson" <[hidden email]>
>>
>> The block size of AES is 128 bits, you therefore need 16 characters
>> or 32 hex
>> digits in the IV.
>>
>> Steve.
>> --
>
>
> Thanks for the reply, I figured that out earlier too, by re-reading
> the documentation
> I have on hand. I always had the impression that if I do in Java
>
>  Cipher cipher = Cipher.getInstance("AES");
>
> it is equivalent to
>
>  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
>
> That is obviously not true. After changing that, that helped a bit.
>
> And after changing the IV to 16 bytes, I got something going, . Now,
> IV is hard-coded to
>
>  unsigned char * _iv[16];
>  for (int i = 0; i < 16; i++)
>      _iv[i] = '1' + i;
>
> in both Java and C.
>
> But it's still not totally right.
>
> Encrypted msg (just text) from Java is decoded "almost" correctly. The
> msg
> consists of multiple lines of text string, but after decrypting it,
> the first line
> always get screwed up and I get garbage. All other lines are decrypted
> correctly.
>
> But encrypted msg from Openssl is decrypted in Java "half correct",
> meaning
> that if I have 8 lines of string, I get about 4 lines correct, the
> others are
> garbage. And the order is indeterminate, the first line is always
> screwed up,
> the second line is ok sometimes, not ok other times. Same for the other
> lines.
>
> I really have no clue why it's like that. I mean, you either decrypt
> the whole
> message correctly, or you don't. I really don't understand how did I get
> "partially correct" decryption :(
>
> thanks for all.
>
> uw
>
This could be due to the fact that in JAVA character are coded in
UNICODE ( Each character uses 2 bytes)
While in C each character is coded with only one byte for each
character. This could be checked from JAVA by squeezing
the first byte of each character.
In C you have to add the 0x00 byte before each character



--
Dr Dominique LOHEZ
ISEN
41, Bd Vauban
F59046 LILLE
France

Phone : +33 (0)3 20 30 40 71
Email: [hidden email]


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Encrypt in Java and decrypt in Openssl (and vice versa)

Bear Giles
Dominique Lohez wrote:

> This could be due to the fact that in JAVA character are coded in
> UNICODE ( Each character uses 2 bytes)
> While in C each character is coded with only one byte for each
> character. This could be checked from JAVA by squeezing
> the first byte of each character.

I would have to check the APIs to be sure, but I thought the Cipher
class took byte[] instead of char[].   You have to specify an "encoding"
to go from chars to bytes, but any of the ISO-8859s would give you one
of the standard enhanced ASCIIs.

Bear
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]