Code Comments
Programming Forum and web based access to our favorite programming groups.Hi. I've got a problem with the RSA ciphered streams. Here is a piece of
code that generates an exception :
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
System.out.print("Generating the RSA key pair...");
KeyPair kp = gen.generateKeyPair();
System.out.println("done.");
Cipher ci = Cipher.getInstance("RSA");
ci.init(Cipher.ENCRYPT_MODE,kp.getPublic());
Cipher cid = Cipher.getInstance("RSA");
cid.init(Cipher.DECRYPT_MODE,kp.getPrivate());
CipherOutputStream cout = new CipherOutputStream(new
FileOutputStream("rsa.dat"),ci);
ObjectOutputStream oout = new ObjectOutputStream(cout);
oout.writeObject(kp.getPrivate().toString());
oout.flush();
oout.close();
CipherInputStream cin = new CipherInputStream(new
FileInputStream("rsa.dat"),cid);
ObjectInputStream oin = new ObjectInputStream(cin); // Exception here
System.out.println(oin.readObject());
oin.close();
The exception is EOFException and it's not very weird because the file
"rsa.dat" is empty after writing to it!! It happens only if object is "big"
( when I try to write some short String, for example, everything's ok ).
When I tried to write an unciphered output ( without using
CipheredOutputStream ) it went well of course.
My question is : can anybody tell me why it happens? What should I do to
write "big" objects to ciphered output stream using ObjectOutputStream
properly?
Thanks for any requests.
Kuba
Post Follow-up to this message-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Stuglik wrote: [snip] > The exception is EOFException and it's not very weird because the > file "rsa.dat" is empty after writing to it!! It happens only if > object is "big" ( when I try to write some short String, for > example, everything's ok ). When I tried to write an unciphered > output ( without using CipheredOutputStream ) it went well of > course. My question is : can anybody tell me why it happens? What > should I do to write "big" objects to ciphered output stream using > ObjectOutputStream properly? > Thanks for any requests. > > Kuba Hi, My experience shows that RSA Cipher implementations are usually only capable of encrypting a single block at a time, after which the entire Cipher object has to be reinitialized. This limits you to 127 bytes with a typical 1024-bit key size (less if you use a proper padding scheme, like all real-world applications should). If you have control over both ends of the system, I'd recommend: 1. Generate a random symmetric key (AES perhaps?) 2. Create a Cipher object using your RSA public key, in Cipher.WRAP_MODE. 3. Use the Cipher.wrap() method to wrap your symmetric key using your RSA key. Put the output in your stream, delimited somehow (length bytes before hand?) 4. Create a Cipher object using the random symmetric key, in Cipher.ENCRYPT_MODE. 5. Put a CipherOutputStream around the Cipher object. 6. Use the CipherOutputStream to encrypt your data. For decryption: 1. Pull in the encrypted key from the beginning of the stream. 2. Create a Cipher object using your RSA private key, in Cipher.UNWRAP_MODE. 3. Use the Cipher.unwrap() method to get the symmetric key. 4. Create a Cipher object using the recovered symmetric key, in Cipher.DECRYPT_MODE. 5. Put a CipherInputStream around the Cipher object. 6. Use the CipherInputStream to decrypt your data. Note that some symmetric ciphers in some modes may have extra information which needs to be sent from one end to the other (although not encrypted), such as an IV. If you're dealing with very much data, you'll also find that this method is a lot faster, since RSA is painfully slow and symmetric ciphers are blazingly fast. Also, it's more space-efficient: at the raw level, RSA encryption takes 127 bytes input and produces 128 bytes out. Any real-world system should utilize a padding system, which uses up maybe 10 bytes, leaving you with just 117 bytes input to 128 bytes output (read: every block of plaintext produces a *bigger* block of ciphertext). Symmetric ciphers, on the other hand, usually encrypt one blocksize worth of bytes to exactly the same size, and also usually get padded only on the last block (read: the ciphertext is bigger than the plaintext, but only by a tiny bit, and by a constant amount, no matter how much plaintext there is). Chris -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.6 (GNU/Linux) iD8DBQFBvnyLgxSrXuMbw1YRAkipAKDBXopmCQ7+ GVcO3SOnfnvMTNsd9gCcD2Gp BWTZpa4drfV1csMuOjFdhpY= =VCVd -----END PGP SIGNATURE-----
Post Follow-up to this messageThanks very much. Now I will know that I shouldn't use it for my program. I'll try the scheme you wrote. Kuba
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.