For Programmers: Free Programming Magazines  


Home > Archive > Java Security > December 2004 > RSA ciphered streams problem









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author RSA ciphered streams problem
Jakub Stuglik

2004-12-13, 4:10 pm

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

2004-12-14, 3:58 am

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

2004-12-14, 4:09 pm

Thanks very much. Now I will know that I shouldn't use it for my program.
I'll try the scheme you wrote.

Kuba


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com