Padding Problem with Blowfish and Crypt::CBC and Java Cipher

H

Hal Vaughan

I have to admit I barely understand any cryptography beyond the simple A=1
type codes my friends and I used in grammar school. I have a server,
running Perl, that takes a file, encrypts it with Blowfish, then MIME
encodes it, sends it out via e-mail. Then I have a Java program that
retrieves the e-mail, MIME decodes it, then decrypts it. I am having no
problem on the Perl end, and any encrypted e-mail I create I can retrieve
and decode. There seems to be no problem with MIME encoding/decoding. The
problem comes when my Java program tries to decrypt the file created and
sent by Perl. I always get:

javax.crypto.BadPaddingException: Given final block not properly padded

When I first set this up, with the Perl code on another computer, I got
errors like that. They stopped, but I was never sure exactly what I did to
solve the problem (and I'm never comfortable with a situation like that).
I tried to examine my changes, and I could never be sure just what fixed
it. Now the Perl code is running on a new system. I'm using a later
version of Crypt::CBC (from 2.08 to 2.12), but I can't see anything in the
changelog that should effect the problem I'm having. I'd also like to
solve the problem once and for all, which means either understanding what
is going wrong with the BadPaddingException, or knowing what to do so Java
has no problem reading the encrypted data Perl sends.

My Perl code to encrypt the data is this:

$cipher = Crypt::CBC->new( { 'key' => $key, iv => $vector,
prepend_iv => 0, 'cipher' => 'Blowfish', 'regenerate_key' => 0 } );
$data = $cipher->encrypt($rawdata);

My Java code to decrypt the data is this:

//sCryptoKey and sCryptoVector are strings with the key and vector
//bCrypto is byte[] of encrypted data
//bDecrypted is byte[] of decrypted data
try {
SecretKeySpec oKey = new SecretKeySpec(sCryptoKey.getBytes("UTF8"),
"Blowfish");
IvParameterSpec oIV = new
IvParameterSpec(sCryptoVector.getBytes("UTF8"));
Cipher oCipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
oCipher.init(Cipher.DECRYPT_MODE, oKey, oIV );
bDecrypted = oCipher.doFinal(bCrypto);
} catch (Exception e) {
//Log the error
sysConfig.log("error", "error decrypting incoming file -- saving to
log
directory: " + e);
}

I'd like to have some better understanding of why I'm getting errors. I'm
not even fully clear on what padding is. I've tried reading up on how
Blowfish works, but I really don't follow it. From what I can see, I
suspect if I change the PKCS5Padding to NoPadding in the Java code should
work, but I'm assuming Padding is just the padding of data on the end. Is
there a way to tell Cipher to figure out the padding, or to take the data
"as is"? I'm also trying to find if there is a way to specify padding on
the Perl end. According to the docs for CBC on CPAN, the padding() method
in CBC is read-only, and I don't see a way to specify the padding in CBC.
I would think as long as I can specify the same padding on both ends there
should be no problem, but, again, there seems to be no way to specify
padding for Crypt::CBC.

Thanks for any help!

Hal
 
H

Hal Vaughan

Hal said:
I have to admit I barely understand any cryptography beyond the simple A=1
type codes my friends and I used in grammar school. I have a server,
running Perl, that takes a file, encrypts it with Blowfish, then MIME
encodes it, sends it out via e-mail. Then I have a Java program that
retrieves the e-mail, MIME decodes it, then decrypts it. I am having no
problem on the Perl end, and any encrypted e-mail I create I can retrieve
and decode. There seems to be no problem with MIME encoding/decoding.
The problem comes when my Java program tries to decrypt the file created
and
sent by Perl. I always get:

javax.crypto.BadPaddingException: Given final block not properly padded

When I first set this up, with the Perl code on another computer, I got
errors like that. They stopped, but I was never sure exactly what I did
to solve the problem (and I'm never comfortable with a situation like
that). I tried to examine my changes, and I could never be sure just what
fixed
it. Now the Perl code is running on a new system. I'm using a later
version of Crypt::CBC (from 2.08 to 2.12), but I can't see anything in the
changelog that should effect the problem I'm having. I'd also like to
solve the problem once and for all, which means either understanding what
is going wrong with the BadPaddingException, or knowing what to do so Java
has no problem reading the encrypted data Perl sends.

My Perl code to encrypt the data is this:

$cipher = Crypt::CBC->new( { 'key' => $key, iv => $vector,
prepend_iv => 0, 'cipher' => 'Blowfish', 'regenerate_key' => 0 }
);
$data = $cipher->encrypt($rawdata);

My Java code to decrypt the data is this:

//sCryptoKey and sCryptoVector are strings with the key and vector
//bCrypto is byte[] of encrypted data
//bDecrypted is byte[] of decrypted data
try {
SecretKeySpec oKey = new
SecretKeySpec(sCryptoKey.getBytes("UTF8"),
"Blowfish");
IvParameterSpec oIV = new
IvParameterSpec(sCryptoVector.getBytes("UTF8"));
Cipher oCipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
oCipher.init(Cipher.DECRYPT_MODE, oKey, oIV );
bDecrypted = oCipher.doFinal(bCrypto);
} catch (Exception e) {
//Log the error
sysConfig.log("error", "error decrypting incoming file -- saving
to
log
directory: " + e);
}

I'd like to have some better understanding of why I'm getting errors. I'm
not even fully clear on what padding is. I've tried reading up on how
Blowfish works, but I really don't follow it. From what I can see, I
suspect if I change the PKCS5Padding to NoPadding in the Java code should
work, but I'm assuming Padding is just the padding of data on the end. Is
there a way to tell Cipher to figure out the padding, or to take the data
"as is"? I'm also trying to find if there is a way to specify padding on
the Perl end. According to the docs for CBC on CPAN, the padding() method
in CBC is read-only, and I don't see a way to specify the padding in CBC.
I would think as long as I can specify the same padding on both ends there
should be no problem, but, again, there seems to be no way to specify
padding for Crypt::CBC.

I found the "padding" setting, and now use this to encrypt:

$cipher = Crypt::CBC->new( { 'key' => $key, iv => $vector,
prepend_iv => 0, 'cipher' => 'Blowfish', 'regenerate_key' => 0,
padding => 'standard' });
$data = $cipher->encrypt($rawdata);

And now I get a different error on the Java end:

javax.crypto.BadPaddingException: Given final block not properly padded

So now it's padding properly (which is should have done anyway, since it is
supposed to default to "standard") but the last block is not being padded
properly. At first I thought I had to change and use the sequence of
"start, crypt, finish" for encoding, but according to the docs, encrypt()
does it all. So is there something I can do to make sure the last block is
padded? Apparently Crypt::CBC isn't doing that.

Thanks!

Hal
 
H

Hal Vaughan

Jim,

Encryption is not something I understand or do well. Your answers were not
only helpful, but your sources were good ones for me to learn from.

Between your post and the sources you cited, I was able to take care of
several tweaks and get everything working.

Hal
 
S

sgillett

Hal,

I am having a similar problem where I am able to decrypt using perl but
not java and wondered if you could help?

With perl I am using:
my $cipher = Crypt::CBC->new($keyword, 'Blowfish');
my $decrypted = $cipher->decrypt($string);

With java I am using:
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decrypted = cipher.doFinal(string);

but get the following error:
javax.crypto.BadPaddingException: Given final block not properly padded

Please can you let me know how you got it working?

Thanks for any help,

Steve.

-------------------------------------
Hal Vaughan wrote:



Encryption is not something I understand or do well. Your answers were
not
only helpful, but your sources were good ones for me to learn from.
Between your post and the sources you cited, I was able to take care of
several tweaks and get everything working.






##-----------------------------------------------#
Article posted with Web Developer's USENET Archiv
http://www.1-script.com/forum
no-spam read and post WWW interface to your favorite newsgroup -
comp.lang.perl.misc - 36524 messages and counting
##-----------------------------------------------##
 
H

Hal Vaughan

sgillett said:
Hal,

I am having a similar problem where I am able to decrypt using perl but
not java and wondered if you could help?

With perl I am using:
my $cipher = Crypt::CBC->new($keyword, 'Blowfish');
my $decrypted = $cipher->decrypt($string);

First I have to add that, like I said in my first post, I have very little
idea what I'm doing with cryptography. I did a search to find an example
of someone sending data back and forth from Perl to Java (and back again),
and basically copied what they did. (That's why I used Blowfish -- I
really have no idea exactly how Blowfish works, but when I did a search on
it, I felt I had every reason to trust it as much as almost anything. I
still hope, someday, to change it to PGP.)

With that having been said, I noticed that you're not setting the padding in
Perl. I'd suggest going back through this thread (use Google Groups if
you're server has expired the earlier articles), and see what I have in my
first posts. That might help.

Hal
With java I am using:
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decrypted = cipher.doFinal(string);

but get the following error:
javax.crypto.BadPaddingException: Given final block not properly padded

Please can you let me know how you got it working?

Thanks for any help,

Steve.

-------------------------------------
Hal Vaughan wrote:



Encryption is not something I understand or do well. Your answers were
not
only helpful, but your sources were good ones for me to learn from.
Between your post and the sources you cited, I was able to take care of
several tweaks and get everything working.







##-----------------------------------------------##
Article posted with Web Developer's USENET Archive
http://www.1-script.com/forums
no-spam read and post WWW interface to your favorite newsgroup -
comp.lang.perl.misc - 36524 messages and counting!
##-----------------------------------------------##
 
S

sgillett

Hi Hal,

Thanks for your suggestion, I am now using
padding => 'standard'
but still get the following error from the java side:
javax.crypto.BadPaddingException: Given final block not properly padded

I have taken a look back at this thread as you suggested, and noticed that
in your earlier posts you had the same problem, and in your post on 23rd
August you were able to get it working with several tweaks.

Can you remember what changes you needed to make?

Thanks,

Steve.




-
##-----------------------------------------------#
Article posted with Web Developer's USENET Archiv
http://www.1-script.com/forum
no-spam read and post WWW interface to your favorite newsgroup -
comp.lang.perl.misc - 36738 messages and counting
##-----------------------------------------------##
 
H

Hal Vaughan

sgillett said:
Hi Hal,

Thanks for your suggestion, I am now using
padding => 'standard'
but still get the following error from the java side:
javax.crypto.BadPaddingException: Given final block not properly padded

I have taken a look back at this thread as you suggested, and noticed that
in your earlier posts you had the same problem, and in your post on 23rd
August you were able to get it working with several tweaks.

Can you remember what changes you needed to make?

Thanks,

Steve.

My best guess is it was a typo (I have a slight learning disability that
makes it very hard, if not almost impossible to spot some typos if
spellchecking or syntax highlighting doesn't catch them). My reasoning for
that is that I looked up the padding info for Perl and Java, experimented
with changing them around, then ended up with putting them both back to
what I had, and after that, it worked. Since the settings were the same as
they were originally, my guess is that I must have mistyped something I
couldn't catch. I never had a problem with Perl decrypting the data,
always with Java decrypting. I guess that's because Java is so picky about
everything and has to have things perfect, whereas Perl is loose enough to
make allowances for, for example, a string not being what was expected.

Below, I've included the important program lines. That includes setting up
the encryption in Perl (the en/de-crypt call is a simple call), and setting
up and using en/de-cryption for Java. I hope that helps!

Hal
===========================

Here's the line I'm using for setting up encryption in Perl:

$cipher = Crypt::CBC->new( { 'key' => $pw, iv => $vector, prepend_iv => 0,
'cipher' => 'Blowfish', 'regenerate_key' => 0 , padding => 'standard'} );

And here's the one I use for setting up decryption in Perl:

$cipher = Crypt::CBC->new( { 'key' => $pw, iv => $vector, prepend_iv => 0,
'cipher' => 'Blowfish', 'regenerate_key' => 0 } );

On the Java side, here's how I set up and call encryption:

//myKey, myVector are strings, bEncrypted is byte[]
try {
SecretKeySpec oKey = new SecretKeySpec(myKey.getBytes(), "Blowfish");
IvParameterSpec oIV = new IvParameterSpec(myVector.getBytes());
Cipher oCipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
oCipher.init(Cipher.ENCRYPT_MODE, oKey, oIV );
bEncrypted = oCipher.doFinal(bData);
} catch (Exception e) {
return "error encrypting string";
}

And here's how I setup and call decryption in Java:

//sCryptoKey, sCryptoVector are strings, bDecrypted is byte[]
try {
SecretKeySpec oKey = new SecretKeySpec(sCryptoKey.getBytes("UTF8"),
"Blowfish");
IvParameterSpec oIV = new IvParameterSpec(sCryptoVector.getBytes("UTF8"));
Cipher oCipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
oCipher.init(Cipher.DECRYPT_MODE, oKey, oIV );
bDecrypted = oCipher.doFinal(bCrypto);
} catch (Exception e) {
return "error decrypting incoming file".getBytes();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top