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

Discussion in 'Perl Misc' started by Hal Vaughan, Aug 12, 2005.

  1. Hal Vaughan

    Hal Vaughan Guest

    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
    Hal Vaughan, Aug 12, 2005
    #1
    1. Advertising

  2. Hal Vaughan

    Hal Vaughan Guest

    Re: Padding Problem UPDATE (Still broken)

    Hal Vaughan wrote:

    > 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
    Hal Vaughan, Aug 12, 2005
    #2
    1. Advertising

  3. Hal Vaughan

    Hal Vaughan Guest

    Re: Padding Problem UPDATE (Still broken)

    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
    Hal Vaughan, Aug 23, 2005
    #3
  4. Hal Vaughan

    sgillett Guest

    Re: Padding Problem UPDATE (Still broken)

    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:




    > 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







    ##-----------------------------------------------#
    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
    ##-----------------------------------------------##
    sgillett, Sep 2, 2005
    #4
  5. Hal Vaughan

    Hal Vaughan Guest

    Re: Padding Problem UPDATE (Still broken)

    sgillett wrote:

    > 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:
    >
    >
    >
    >
    >> 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

    >
    >
    >
    >
    >
    >
    >
    > ##-----------------------------------------------##
    > 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!
    > ##-----------------------------------------------##
    Hal Vaughan, Sep 2, 2005
    #5
  6. Hal Vaughan

    sgillett Guest

    Re: Padding Problem UPDATE (Still broken)

    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
    ##-----------------------------------------------##
    sgillett, Sep 5, 2005
    #6
  7. Hal Vaughan

    Hal Vaughan Guest

    Re: Padding Problem UPDATE (Still broken)

    sgillett wrote:

    > 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();
    }
    Hal Vaughan, Sep 5, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ChrisO
    Replies:
    9
    Views:
    167
    A. Sinan Unur
    Aug 13, 2004
  2. Homer J.
    Replies:
    3
    Views:
    118
    Homer J.
    Nov 14, 2004
  3. Replies:
    1
    Views:
    171
  4. Waylen Gumbal

    Crypt::CBC vs individual cipher module differs?

    Waylen Gumbal, Mar 3, 2008, in forum: Perl Misc
    Replies:
    3
    Views:
    147
    Waylen Gumbal
    Mar 8, 2008
  5. Hal Vaughan

    Problem With Crypt::CBC

    Hal Vaughan, Aug 20, 2008, in forum: Perl Misc
    Replies:
    3
    Views:
    183
    Eric Pozharski
    Aug 20, 2008
Loading...

Share This Page