1

I am trying to encrypt some sample text from a private key file that has been generated with a SHA-256 with RSA password. This private key has been generated from Verisign (CA authority) and passed to us.

Here is the code I am using:

public class EncryptionUtil {
    public static final String ALGORITHM = "RSA";
    public static final String PRIVATE_KEY_FILE = "C:\\keys\\private.key";
    public static byte[] encrypt(String text, PrivateKey key) {
        byte[] cipherText = null;
        try {
            final Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            cipherText = cipher.doFinal(text.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cipherText;
    }
    public static void main(String[] args) {
        try {
            final String originalText = "This is a test";
            // Encrypt
            final PrivateKey privateKey = readPrivateKey(new File(
                    PRIVATE_KEY_FILE));
            final byte[] cipherText = encrypt(originalText, privateKey);
            // Printing
            System.out.println("Original: " + originalText);
            System.out.println("Encrypted: " + cipherText.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static PrivateKey readPrivateKey(File file) throws IOException,
            GeneralSecurityException {
        DataInputStream input = new DataInputStream(new FileInputStream(file));
        try {
            byte[] bytes = new byte[(int) file.length()];
            input.read(bytes);
            KeySpec spec = new PKCS8EncodedKeySpec(bytes);
            try {
                return KeyFactory.getInstance("RSA").generatePrivate(spec);
            } catch (InvalidKeySpecException ex) {
                return KeyFactory.getInstance("DSA").generatePrivate(spec);
            }
        } finally {
            input.close();
        }
    }
}

But at the return KeyFactory.getInstance("RSA").generatePrivate(spec); (and also return KeyFactory.getInstance("DSA").generatePrivate(spec); line) I got the following error:

java.security.spec.InvalidKeySpecException: Inappropriate key specification: invalid key format
    at sun.security.provider.DSAKeyFactory.engineGeneratePrivate(DSAKeyFactory.java:156)
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)

Do you know what I am missing?

My private key looks like:

-----BEGIN ENCRYPTED PRIVATE KEY-----
base64 private key
-----END ENCRYPTED PRIVATE KEY-----

So I tried to decode64 the byte array and now got the following error:

java.security.spec.InvalidKeySpecException: Inappropriate key specification: IOException : DER input, Integer tag error
    at sun.security.provider.DSAKeyFactory.engineGeneratePrivate(DSAKeyFactory.java:156)
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)

When the private key is not encrypted the previous code works perfectly.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Thiago
  • 137
  • 1
  • 2
  • 10
  • Note that in your "editing" you forgot to go back to `"RSA"` from `"DSA"`... – Maarten Bodewes Apr 06 '15 at 18:12
  • Yes, I got the exat same error from RSA actually java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DER input, Integer tag error at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217) at java.security.KeyFactory.generatePrivate(KeyFactory.java:372) – Thiago Apr 06 '15 at 18:30
  • I've got little time now, but take a look at the Bouncy Castle libraries, the core library has a PEM decoder in it (make sure you use the latest version). – Maarten Bodewes Apr 06 '15 at 18:33
  • Thanks, but let's suppose I was using something like this that seems more generical, what would be the thing to do in order to fix this error and go further? Regarding the Bouncy Castle do you any example of how it would fit in my sample? Thanks, – Thiago Apr 06 '15 at 18:38
  • For what I found on the Net this problem is because the key is encrypted. It will only works with an unencrypted private key. But how can I pass thje password? – Thiago Apr 06 '15 at 19:53
  • Problem is that I'm not 100% sure about the type of the key inside (probably PKCS#8, but it could also be PKCS#12). Standard Java knows how to handle *decrypted* PKCS#8 private keys using `KeyFactory` and PKCS#12 containers using `KeyStore`. Are you on a unix machine? – Maarten Bodewes Apr 06 '15 at 19:56
  • I am on a windows machine but as I previously commented I am using a encrypted private key. Probably a PKCS#8. It seems that this exception thrown is related to the fact that the key is encrypted. – Thiago Apr 06 '15 at 20:35
  • You could try the code [here](http://stackoverflow.com/a/15124237/589259). Problem is, as stated, I cannot as I don't have the private key or the secret key/password of course... – Maarten Bodewes Apr 06 '15 at 22:25
  • Thanks, I tried but in my case the object is PKCS8EncryptedPrivateKeyInfo and not PEMEncryptedKeyPair – Thiago Apr 07 '15 at 14:56

0 Answers0