Encrypting with RSA private key in Java

wadesworld picture wadesworld · Sep 8, 2009 · Viewed 38k times · Source

I'm trying to encrypt some content with an RSA private key.

I'm following this example: http://www.junkheap.net/content/public_key_encryption_java

but converting it to use private keys rather than public. Following that example, I think what I need to do is:

  • Read in a DER-format private key
  • Generate a PCKS8EncodedKeySpec
  • call generatePrivate() from KeyFactory to get a private key object
  • Use that private key object with the Cipher object to do the encryption

So, the steps:

The key was generated from openssl with:

openssl genrsa -aes256 -out private.pem 2048

and then was converted to DER format with:

openssl rsa -in private.pem -outform DER -out private.der

I generate the PKCS8EncodedKeySpec with:

byte[] encodedKey = new byte[(int)inputKeyFile.length()];

try {
    new FileInputStream(inputKeyFile).read(encodedKey);
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
return privateKeySpec;

And then generate the private key object with:

PrivateKey pk = null;

try {
    KeyFactory kf = KeyFactory.getInstance(RSA_METHOD);
    pk = kf.generatePrivate(privateKeySpec);
} catch (NoSuchAlgorithmException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (InvalidKeySpecException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
return pk;

However, on the call to:

pk = kf.generatePrivate(privateKeySpec);

I get:

java.security.spec.InvalidKeySpecException: Unknown key spec.
at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePrivate(DashoA12275)
at com.sun.net.ssl.internal.ssl.JSA_RSAKeyFactory.engineGeneratePrivate(DashoA12275)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:237)

Questions:

  • Is the general approach right?
  • Is the PCKS8EncodedKeySpec the right keyspec to use?
  • Any thoughts on the invalid key spec error?

Answer

ZZ Coder picture ZZ Coder · Sep 8, 2009

You can't encrypt with private key. If JCE allows you to do that, it's just by accident.

You need to use signature. Here are the code snippet to do that,

signer = Signature.getInstance("SHA1withRSA");
signer.initSign(privateKey); // PKCS#8 is preferred
signer.update(dataToSign);
byte[] signature = signer.sign();