У меня есть метод, который генерирует пару ключей, как показано ниже:
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
закодированные байты ключа. В чем здесь разница?