RSA ciphered streams problem  
Author Message
Jakub Stuglik





PostPosted: 2004-12-13 17:04:00 Top

java-programmer, RSA ciphered streams problem 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



 
klynn47





PostPosted: 2004-12-14 0:24:00 Top

java-programmer >> RSA ciphered streams problem Have you tried printing the output to the screen to make sure that
something is being written? The only think I could think might be the
problem is that there wasn't enough time to write the whole object. You
might try two methods that use thread synchronization. That way, if the
write operation and read operation are synchronized, then the read
can't happen until the write is finished.

 
Jakub Stuglik





PostPosted: 2004-12-14 2:23:00 Top

java-programmer >> RSA ciphered streams problem You're right - I tried to put it on the screen and "big" objects aren't
written to the stream - there's nothing on the screen after writing
operation ( I also commented code lines responsible for reading the object
to make sure there's enough time to write the whole object but it wouldn't
help ). Do you maybe have any idea how to deal with such a problem?
Thanks for any suggestions.

Kuba


 
 
Jakub Stuglik





PostPosted: 2004-12-14 2:29:00 Top

java-programmer >> RSA ciphered streams problem 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




 
 
Chris





PostPosted: 2004-12-14 13:39:00 Top

java-programmer >> RSA ciphered streams problem -----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-----
 
 
Jakub Stuglik





PostPosted: 2004-12-15 2:43:00 Top

java-programmer >> RSA ciphered streams problem Thanks very much. Now I will know that I shouldn't use it for my program.
I'll try the scheme you wrote.

Kuba