my dog learned polymorphism*
The moose likes Java in General and the fly likes CipherOutputStream and JarOutputStream Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "CipherOutputStream and JarOutputStream" Watch "CipherOutputStream and JarOutputStream" New topic
Author

CipherOutputStream and JarOutputStream

Per Engstrom
Greenhorn

Joined: Feb 11, 2010
Posts: 9
Hi,

I have a problem with encrypting a file while writing it into a Jar file.

I belive it it because only the number of bytes that I write into the CipherOutputStream are written into the JarOutputStream.
Writing the same stream into two entries (one not encoded) result in two entries of the same size.
But the encoded data increase in size if I write it into a FileOutputStream.

I get a similar problem if I forget to close the FileOutputStream.
But if I close the JarOutputStream I am unable to add more entries (!)...

I've tried to add a couple of flush() requests, but it doesn't seem to help.

Any suggestions?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19680
    
  19

Skip the CipherOutputStream and use the Cipher directly. Instead of writing bytes to the CipherOutputStream you call the Cipher's update() method. At the end you call doFinal() and write those to the JarOutputStream as well. In short:
Reading is similar, although I think you can use CipherInputStream there.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Per Engstrom
Greenhorn

Joined: Feb 11, 2010
Posts: 9
Thanks!

Using the Cipher directly manages to copy the last 8 bytes.
Diffing the entries show that the rest of the files are identical.


But I still have some problems...

If I decrypt with the CipherInputStream the decryption completes w/o exception.
But the decrypted file is corrupt.


If I decrypt with the Cipher directly I get the following exception:

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.DESedeCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)


What's going on here?!?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19680
    
  19

How did you create the Cipher? Did you remember to initialize it in decrypt mode? Because I tested my code with a matching decryption part (both using Cipher directly and using CipherInputStream) and the files were exactly equal to the source files. The files inside the JAR file were different.
Per Engstrom
Greenhorn

Joined: Feb 11, 2010
Posts: 9
I think the cipher is correct... When writing to a FileOutStream, I can encrypt - decrypt and get the original back.

However after trying a few combinations I get the following (no Jar file involved):

StreamEncrypt - StreamDecrypt: OK
CipherEncrypt - StreamDecrypt: OK
CipherEncrypt - CipherDecrypt: OK
StreamEncrypt - CipherDecrypt: javax.crypto.BadPaddingException: Given final block not properly padded

Recap of Jar problem:

StreamEncrypt: Entry missing last 8 bits
CipherEncrypt: Entry contains the last 8 bits
StreamDecrypt: Result is corrupt
CipherDecrypt: javax.crypto.BadPaddingException: Given final block not properly padded

If I unpack the Jar file the encrypted entries diff with the direct-to-file-encrypted version
But the Jar file is generally ok, because non-encrypted files are correct.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19680
    
  19

How did you encrypt using the stream? The way you programmed it, it may not have added the final data, and that's what's then causing this error. That final data is usually what is written when the CipherOutputStream is closed, but we've already found out we can't do that - it will close the JarOutputStream as well, so no more entries can be written.
Per Engstrom
Greenhorn

Joined: Feb 11, 2010
Posts: 9
With input from the following thread I think the problem is with a corrupt key.

http://www.coderanch.com/t/133352/Security/BadPaddingException-DES

The key is converted into a string and stored.
That may be the reason why the CipherEncode-CipherDecode does not work...
The reason why the CipherStreams doesn't work is likely a combination of both failing to flush and key corruption...

Thanks for the help!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: CipherOutputStream and JarOutputStream