4

I am trying to convert EC private key

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIE2tzb8O0gBVw2IFOB/B8l1Ztjax3ut4DeNtuC3UMmZ6oAoGCCqGSM49
AwEHoUQDQgAEayT6Tv8zZlpIUOKHEYnmsKZyTaqOHajL0InS4c5tK4fhkHZDSWUa
3tPl1ibIXt0LvaxHk47h0Tc4SGr3Ex8Bhg==
-----END EC PRIVATE KEY----- 

to Private Key

 -----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTa3Nvw7SAFXDYgU4
H8HyXVm2NrHe63gN4224LdQyZnqhRANCAARrJPpO/zNmWkhQ4ocRieawpnJNqo4d
qMvQidLhzm0rh+GQdkNJZRre0+XWJshe3Qu9rEeTjuHRNzhIavcTHwGG
-----END PRIVATE KEY-----

It's very easy when you execute openSsl command like this:

openssl pkcs8 -topk8 -nocrypt -in ec1.pem -out ec2.pem

But i want to do this in Java way and didn't find any solution (tried so many from stackoverflow). So i have for now following class:

        ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
        KeyPairGenerator keyPair = KeyPairGenerator.getInstance("ECDSA", "BC");

        // Create a secure random number generator using the SHA1PRNG algorithm
        SecureRandom secureRandomGenerator = SecureRandom.getInstance("SHA1PRNG");
        keyPair.initialize(ecNamedCurveParameterSpec, secureRandomGenerator);
    

Then i generate KeyPair and get PrivateKey in ECPrivateKey Object:

KeyPair pair =keyPair.generateKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) pair.getPrivate();
StringWriter sw = new StringWriter();

        try (JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(sw);) {
            jcaPEMWriter.writeObject(privateKey);
        }

String pemFormat = sw.toString();

This string pemFormat is actually PEM format that starts with BEGIN EC PRIVATE KEY

How can i convert it just to BEGIN PRIVATE KEY?

I assume that should be a way if openSsl can do it.

master17
  • 139
  • 2
  • 12
  • This bog post may help: [Create and read PKCS #8 format private key in java program.](http://techxperiment.blogspot.com/2016/10/create-and-read-pkcs-8-format-private.html) – Reinier Torenbeek Apr 04 '21 at 19:57

1 Answers1

4

A conversion from the SEC1/PEM (-----BEGIN EC PRIVATE KEY-----...) to the PKCS#8/PEM format (-----BEGIN PRIVATE KEY-----...) is not needed at all, because privateKey.getEncoded() returns the key already in PKCS#8 format. So it only needs to be exported as PEM e.g. with a PemWriter:

import org.bouncycastle.util.io.pem.PemWriter;

...

// Your code
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
...
ECPrivateKey privateKey = (ECPrivateKey)pair.getPrivate();
System.out.println(privateKey.getFormat()); // PKCS#8

// Export as PKCS#8 PEM encoded key via PemWriter
StringWriter stringWriter = new StringWriter();
try (PemWriter pemWriter = new PemWriter(stringWriter)){
    pemWriter.writeObject((PemObjectGenerator)new PemObject("PRIVATE KEY", privateKey.getEncoded()));
}
String pkcs8PEM = stringWriter.toString();
System.out.println(pkcs8PEM); // -----BEGIN PRIVATE KEY-----MIGTAg...-----END PRIVATE KEY-----

You can check the format in an ASN.1 parser, e.g. https://lapo.it/asn1js.


However, if you are really looking for an explicit conversion of a SEC1/PEM key into a PKCS#8/PEM key, then the import of a SEC1/PEM key is described e.g. here. The imported key can then be exported as a PKCS#8/PEM key using a PemWriter as in the example above.

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Thanks!!! It really helped me to handle. I also checked by converting back to EC pem format and the same value. – master17 Apr 06 '21 at 08:25
  • What's the type of pair object in "(ECPrivateKey)pair.getPrivate()". I am trying to read my key from a String and return PrivateKey object. Can you share what do I need to update in the above snippet? – dhamu Jul 13 '21 at 17:54
  • @dhamu - Please post a new question with all the information needed to answer. If necessary you can reference this post. – Topaco Jul 13 '21 at 17:58