I have a method that generates a keypair as below:
public void create() throws Exception{
StringWriter pemStrWriter = new StringWriter();
JcaPEMWriter pemWriter = new JcaPEMWriter(pemStrWriter);
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");
ECGenParameterSpec spec = new ECGenParameterSpec("secp256r1");
g.initialize(spec);
KeyPair keyPair = g.generateKeyPair();
pemWriter.writeObject(keyPair.getPrivate());
pemWriter.close();
BufferedWriter writer = new BufferedWriter(new FileWriter("privatekeyjca.pem"));
writer.write(pemStrWriter.toString());
writer.close();
writer = new BufferedWriter(new FileWriter("publickeyjca.pem"));
pemStrWriter = new StringWriter();
pemWriter = new JcaPEMWriter(pemStrWriter);
pemWriter.writeObject(keyPair.getPublic());
pemWriter.close();
writer.write(pemStrWriter.toString());
writer.close();
}
Below is how the generated private key looks like :
-----BEGIN EC PRIVATE KEY----- MHcCAQEEIHKaV0qkw5ZyJlaH8oEGEGg066O/zH3zxUTGM+p1bwKPoAoGCCqGSM49 AwEHoUQDQgAEKfR0VmGHRDqtnRkSPHrAWYhG8c2W2tI/tyGhqs19/U2d/DRy8f/z BEnl3knytYsZtP5og0xoNODnsM0+k8xyOA== -----END EC PRIVATE KEY-----
I have another method that reads the private key as below:
private void readKey(String key) {
StringReader stringReader = new StringReader(key);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PEMParser pemParser = new PEMParser(stringReader);
PrivateKeyInfo kp = (PrivateKeyInfo) pemParser.readObject();
Key key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(kp.getEncoded()));
}
While reading, I am getting an exception :
Exception in thread "main" java.lang.ClassCastException: org.bouncycastle.openssl.PEMKeyPair cannot be cast to org.bouncycastle.asn1.pkcs.PrivateKeyInfo
While writing the privatekey in a pemfile, I am using JCAPemWriter as you see above. But, if I don't use that and use the below code to write the pem, then the reader method works perfectly fine.
public static void main(String args[]) throws Exception{
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");
ECGenParameterSpec spec = new ECGenParameterSpec("secp256r1");
g.initialize(spec);
KeyPair keyPair = g.generateKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
String publicKeyContent = Base64.encode(publicKeyBytes);
String publicKeyFormatted = "-----BEGIN PUBLIC KEY-----" + System.lineSeparator();
for (final String row:
Splitter
.fixedLength(64)
.split(publicKeyContent)
)
{
publicKeyFormatted += row + System.lineSeparator();
}
publicKeyFormatted += "-----END PUBLIC KEY-----";
BufferedWriter writer = new BufferedWriter(new FileWriter("publickey.pem"));
writer.write(publicKeyFormatted);
writer.close();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
String privateKeyContent = Base64.encode(privateKeyBytes);
String privateKeyFormatted = "-----BEGIN PRIVATE KEY-----" + System.lineSeparator();
for (final String row:
Splitter
.fixedLength(64)
.split(privateKeyContent)
)
{
privateKeyFormatted += row + System.lineSeparator();
}
privateKeyFormatted += "-----END PRIVATE KEY-----";
BufferedWriter writer2 = new BufferedWriter(new FileWriter("privatekey.pem"));
writer2.write(privateKeyFormatted);
writer2.close();
}
Since, using the JCAPemWriter makes the code concise, I wanted to use that rather than splitting the Base64
encoded key bytes. What is the difference here?