views:

21

answers:

1

I'm trying to encrypt some binary data in Java with a public key as described on this useful page: http://www.junkheap.net/content/public_key_encryption_java

As directed by the page, I created public and private keys using the commands:

openssl genrsa -aes256 -out private.pem 2048
openssl rsa -in private.pem -pubout -outform DER -out public.der

Now I save encrypt some data with a small program:

public class Rsa {

    public static void main(String[] args) throws Exception, IOException {
        File keyFile = new File("public.der");
        byte[] encodedKey = new byte[(int) keyFile.length()];

        new FileInputStream(keyFile).read(encodedKey);

        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);

        KeyFactory kf = KeyFactory.getInstance("RSA");
        PublicKey pk = kf.generatePublic(publicKeySpec);

        Cipher rsa = Cipher.getInstance("RSA");

        rsa.init(Cipher.ENCRYPT_MODE, pk);

        FileOutputStream fileOutputStream = new FileOutputStream(
                "encrypted.rsa");
        OutputStream os = new CipherOutputStream(fileOutputStream, rsa);

        byte[] raw = new byte[245];
        raw[0] = 4;

        os.write(raw);
        os.flush();
        os.close();


    }
}

The above code works, but when I change the size of the byte array to 246, it produces a zero-length file!

What am I doing wrong?

+2  A: 

CipherOutputStream tends to swallow exceptions generated by the Cipher and OutputStream objects it wraps. The Sun RSA implementation will not encrypt more than than M-11 bytes, where M is the length in bytes of the modulus. This is true for the default PKCS1Padding, which is what you should always use unless you really know what you are doing. You can specify NoPadding and thereby get the full M bytes.

RSA is not the correct choice for encrypting bulk data. The generally accepted method for encrypting data with RSA is to generate a random symmetric session key K. e.g. an AES key, encrypt the data with the symmetric algorithm with K, then encrypt K using the RSA keys of all the receipients.

GregS
Thanks Greg - I wish I'd known that 4 hours ago!
Mark