Невозможно прочитать сгенерированный BouncyCastle приватный ключ в Java - PullRequest
1 голос
/ 04 мая 2020

У меня есть метод, который генерирует пару ключей, как показано ниже:

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();
}

Ниже показано, как выглядит сгенерированный закрытый ключ:

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHKaV0qkw5ZyJlaH8oEGEGg066O/zH3zxUTGM+p1bwKPoAoGCCqGSM49
AwEHoUQDQgAEKfR0VmGHRDqtnRkSPHrAWYhG8c2W2tI/tyGhqs19/U2d/DRy8f/z
BEnl3knytYsZtP5og0xoNODnsM0+k8xyOA==
-----END EC PRIVATE KEY-----

У меня есть другой метод, который читает закрытый ключ, как показано ниже:

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()));
}

При чтении я получаю исключение:

Exception in thread "main" java.lang.ClassCastException:
org.bouncycastle.openssl.PEMKeyPair cannot be cast to
org.bouncycastle.asn1.pkcs.PrivateKeyInfo

При записи приватного ключа в pemfile Я использую JCAPemWriter, как вы видите выше. Но, если я не использую это и использую приведенный ниже код для написания pem, тогда метод reader работает отлично.

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();
}

Поскольку использование JCAPemWriter делает код лаконичным, я хотел использовать это вместо того, чтобы разбивать Base64 закодированные байты ключа. В чем здесь разница?

...