3

I'm new to the field of cryptography and trying out a sample program to understand PKI key exchange mechanism. I tried creating a self signed certificate using openssl

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.cer

This gave me a certificate file that i can publish to my client program and a private key file that i user to decrypt the text encrypted by client programs. I am able to encrypt plain text using the certificate file, but facing problem in obtaining the private key. How do i read the private key from the key file to use it in decryption.

My understanding with Key exchange is, I have a public and private key either self signed or obtained from CA; publish the public key to applications (sender) that intend to send me message. The sender encrypts a symmetric key with the published public key and the receiver decrypts the message using the private key and thus both parties have exchanged symmetric key for further bi-directional cryptography.

While i try to extract the private key using the below java code

public class RSAToy {


    private static final String BEGIN_RSA_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n"
            + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDW6ofjl8o8sjGg\n"
            + "ANqLneMcrq+xUYVRnKT1mGtboMYHJqtgNIbCzMo4Ym4Uw5+m1JEa2fxbcExp1JAK\n"
            + "A3Cmih+KaJ/gjyaJDKHrTuRN7hs4oSo6aPTIAW3euuqWH7xrFOIvXRRIqRWu4oir\n"
            + "xEjjyQ2IxqkPssf+AUAkz9DiH6phGIaXHXocIsCSEssZWkYd7WZ0HYL3Bfz+W4aY\n"
            + "+PfKDwflMLknsWOkmzc8N+i4Bac3IxOuFhwmg3y2YQq//ZkkaJv3OVIjj6v2OuRY\n"
            + "vgfrPs9dwkshloxp8HRDlA5upXiBiv3JOawbkBUs+bmxzjTNT+vyliKb4qq9ZCAF\n"
            + "ikV5BKazAgMBAAECggEADao137O8CSXvX9QOEUiFs0IsK6MaTfkex/rcAKR1UukT\n"
            + "hndwhhxNU052310c3pevbjyj/hBi22vHiMt1MzGfFcbXO4j+k0I5XWPTwly8YFpm\n"
            + "+/XGcp0cpkfOOKNl8I0QYKCTdJdDqK4AsKM3WzxiXur6vuPIMY9Uy8Jm7qnCxI+T\n"
            + "xoYW857hX9caDvDS+YyMzHFHfcuqI0//4AzjgxgIqy8D0w9u4Xr61mAsLYNsXAUt\n"
            + "ZPOXoI8KhQ7DAAYzmY3OnBRr3fQbM2yXVxdW9Tv6bhmFrpuicUHfMRJrnjzK1b4O\n"
            + "nPtn5542rVzCXe6FWu1c98Gw0S+oo3G8gfgg/IpukQKBgQD4cnXrMGV2ETE3rWjD\n"
            + "drEo0pGJ8UCAwl08xBRY5dlK6SkfsnMOiZhQIsFLqMvknEmYNarWdu4Bmu3lgoo1\n"
            + "/JO0UGUifbklhDTQoy7q12jzCLMMQMSm5ziTCehJ2lOMI+Z+gD+AQD9ltCUBCQrR\n"
            + "s8YhAR8TH5aDtb2kkohRrDufKwKBgQDdcx2LvnjaR1lB9MQ85snTx2LQt26ewyRd\n"
            + "2zxBBQtNGQvmP0mj3t/88tHu+MPQCCvHpFiPdcs7VN/SEfE6vw9R0YY6b/YIKelm\n"
            + "uj9t5Ar2EZtUvbiVCYyKXAl5tgXNAESTP8LDidhQ41UjJS0ZaVwXbCwDVDZqS4NY\n"
            + "JGSeq9SSmQKBgQCGQ40YOcJLKQVZGnyoTUd2UT1Xt6ntK5ypjymT1Ts1sYWI3K4z\n"
            + "KAbJH88oLSNq+08GU9JsLj93XJu90WsRu9qyslPFbP4WmTjVm6pqPVk5JfVk5Meh\n"
            + "jwlS5SLEbpmB/ZC9wl8O1ymrs8vfoFxZcXbcNTfu5L45lYjUHGBRCuv5mwKBgBN6\n"
            + "AGs+AVsRU2RdprTEh5O8wZAh0fTcrOIkWhRN4USSo11Iy61B+OlCYfxmnLI7Rb51\n"
            + "UeSsM4ewW08ajODh1PMZPnj9R+JH7WM/ljyQBfbGbabyWL2i7V1t4td1juUM1Psu\n"
            + "bG7OPNxAYkiJCIJnpdXZibVxPqfypEaoTME306ZhAoGBAO9E1RbKR+9p/h7xzXPE\n"
            + "0vFyN0ItW2Mu3ESE4VRplYx4ht/zZ4gBJMHLNNQCk3IQGflizJ6+On74z6RnYxAy\n"
            + "jiF9zLqj8NKy24wrWithYepG4C0JL6xg2k3gYLxyuccXak06D0ABDxnwJcXrZvmq\n"
            + "zuhsR8X+g3gxaGr7dTgMcZ2J\n"
            + "-----END PRIVATE KEY-----";


    public static void main(String[] args) throws Exception {

        // Remove the first and last lines

        String privKeyPEM = BEGIN_RSA_PRIVATE_KEY.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
        privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");
//        System.out.println(privKeyPEM);

        // Base64 decode the data

        byte [] encoded = Base64.decodeBase64(privKeyPEM);

        // PKCS8 decode the encoded RSA private key

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

//        RSAPrivateKeySpec keySpec = new R
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey privKey = kf.generatePrivate(keySpec);

        // Display the results

        System.out.println(privKey);
    }
}

I am getting

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=111, too big.
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)

How do I fix it up and extract the private key to decrypt my encoded message. Any help is much appreciated.

3 Answers 3

3

When OpenSSL creates a private key, it uses its own format; actually, the raw ASN.1-based format which is described in PKCS#1. This is not PKCS#8, which is a wrapper around that format.

You can convert the private key into PKCS#8 format like this:

openssl pkcs8 -in privateKey.key -topk8 -nocrypt -out privateKey.pk8

The "-nocrypt" option is because PKCS#8 optionally supports password-based encryption of the private key. You can add -outform DER to avoid PEM encoding ("PEM" is Base64 plus a pair of headers, which you remove in your code).

0

You're creating an x509 certificate, but then try to import a PKCS8 format key. The exported key isn't compatible. You need to either export a PKCS8 DER / PEM (depending on which one Java wants), or change your code to import x509 keys.

2
  • X.509 is a format for storing the public key while PKCS#8 is a format for storing the private key. The two are orthogonal issues. What OpenSSL uses by default to store a private key is neither PKCS#8 nor X.509 (X.509 makes no sense for a private key; PKCS#8 does make sense and OpenSSL supports it, but this is not its default private key storage format). Commented Nov 7, 2012 at 14:16
  • Ah, I seem to have misunderstood.
    – Polynomial
    Commented Nov 7, 2012 at 14:18
0

If you want to parse on Windows as well you should use

keyStr.replaceAll("(-+BEGIN RSA PRIVATE KEY-+\\r?\\n|-+END RSA PRIVATE KEY-+\\r?\\n?)", "");

to substitute DER string.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .