Unable to read BouncyCastle generated privatekey in Java

夙愿已清 提交于 2020-05-16 02:28:45

问题


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?

来源:https://stackoverflow.com/questions/61589895/unable-to-read-bouncycastle-generated-privatekey-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!