Come leggere il file .pem per ottenere la chiave privata e pubblica

Sto scrivendo un piccolo pezzo di codice che legge la chiave pubblica e privata memorizzata nel file .pem. Sto usando i seguenti comandi per generare le chiavi.

Sotto comando per generare coppia di chiavi.

$openssl genrsa -out mykey.pem 2048 

Questo comando per generare la chiave privata

 $openssl pkcs8 -topk8 -inform PEM -outform PEM -in mykey.pem \ -out private_key.pem -nocrypt 

e questo comando per ottenere la chiave pubblica.

 $ openssl rsa -in mykey.pem -pubout -outform DER -out public_key.der 

Ho scritto due metodi che leggono rispettivamente la chiave privata e la chiave pubblica.

  public PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception { File f = new File(filename); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte[] keyBytes = new byte[(int) f.length()]; dis.readFully(keyBytes); dis.close(); String temp = new String(keyBytes); String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----\n", ""); privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", ""); //System.out.println("Private key\n"+privKeyPEM); Base64 b64 = new Base64(); byte [] decoded = b64.decode(privKeyPEM); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded); KeyFactory kf = KeyFactory.getInstance(algorithm); return kf.generatePrivate(spec); } public PublicKey getPemPublicKey(String filename, String algorithm) throws Exception { File f = new File(filename); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte[] keyBytes = new byte[(int) f.length()]; dis.readFully(keyBytes); dis.close(); String temp = new String(keyBytes); String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", ""); publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", ""); Base64 b64 = new Base64(); byte [] decoded = b64.decode(publicKeyPEM); X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded); KeyFactory kf = KeyFactory.getInstance(algorithm); return kf.generatePublic(spec); } 

Sento che questo è un modo ingenuo per farlo. Non ho potuto ottenere un modo migliore di farlo su internet. Qualcuno può suggerirmi qual è il modo migliore di scrivere lo stesso codice per gestire i casi generici. Non voglio usare alcun tipo di libreria di terze parti.
Ho una conoscenza molto basilare del canto / della crittografia e difficilmente utilizzo qualsiasi API di sicurezza java. Quindi se non ho senso da qualche parte, per favore, fai notare.

Prova questo corso.

 package groovy; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; public class RSA { private static String getKey(String filename) throws IOException { // Read key from file String strKeyPEM = ""; BufferedReader br = new BufferedReader(new FileReader(filename)); String line; while ((line = br.readLine()) != null) { strKeyPEM += line + "\n"; } br.close(); return strKeyPEM; } public static RSAPrivateKey getPrivateKey(String filename) throws IOException, GeneralSecurityException { String privateKeyPEM = getKey(filename); return getPrivateKeyFromString(privateKeyPEM); } public static RSAPrivateKey getPrivateKeyFromString(String key) throws IOException, GeneralSecurityException { String privateKeyPEM = key; privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----\n", ""); privateKeyPEM = privateKeyPEM.replace("-----END PRIVATE KEY-----", ""); byte[] encoded = Base64.decodeBase64(privateKeyPEM); KeyFactory kf = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(keySpec); return privKey; } public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException { String publicKeyPEM = getKey(filename); return getPublicKeyFromString(publicKeyPEM); } public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException { String publicKeyPEM = key; publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", ""); publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", ""); byte[] encoded = Base64.decodeBase64(publicKeyPEM); KeyFactory kf = KeyFactory.getInstance("RSA"); RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded)); return pubKey; } public static String sign(PrivateKey privateKey, String message) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException { Signature sign = Signature.getInstance("SHA1withRSA"); sign.initSign(privateKey); sign.update(message.getBytes("UTF-8")); return new String(Base64.encodeBase64(sign.sign()), "UTF-8"); } public static boolean verify(PublicKey publicKey, String message, String signature) throws SignatureException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException { Signature sign = Signature.getInstance("SHA1withRSA"); sign.initVerify(publicKey); sign.update(message.getBytes("UTF-8")); return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8"))); } public static String encrypt(String rawText, PublicKey publicKey) throws IOException, GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return Base64.encodeBase64String(cipher.doFinal(rawText.getBytes("UTF-8"))); } public static String decrypt(String cipherText, PrivateKey privateKey) throws IOException, GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); return new String(cipher.doFinal(Base64.decodeBase64(cipherText)), "UTF-8"); } } Required jar library "common-codec-1.6" 

Un’opzione è usare PEMParser di bouncycastle :

Classe per l’analisi di stream codificati OpenSSL PEM contenenti certificati X509, chiavi codificate PKCS8 e oggetti PKCS7.

Nel caso degli oggetti PKCS7 il lettore restituirà un object ContentInfo CMS. Le chiavi pubbliche verranno restituite come oggetti SubjectPublicKeyInfo ben formati, le chiavi private verranno restituite come oggetti PrivateKeyInfo ben formati. Nel caso di una chiave privata, in genere viene restituito PEMKeyPair se la codifica contiene sia la definizione della chiave pubblica che privata. CRL, certificati, richieste PKCS # 10 e certificati di attributo generano la class di titolari di BC appropriata.

Ecco un esempio di utilizzo del codice di test di Parser :

 package org.bouncycastle.openssl.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMDecryptorProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.util.test.SimpleTest; /** * basic class for reading test.pem - the password is "secret" */ public class ParserTest extends SimpleTest { private static class Password implements PasswordFinder { char[] password; Password( char[] word) { this.password = word; } public char[] getPassword() { return password; } } public String getName() { return "PEMParserTest"; } private PEMParser openPEMResource( String fileName) { InputStream res = this.getClass().getResourceAsStream(fileName); Reader fRd = new BufferedReader(new InputStreamReader(res)); return new PEMParser(fRd); } public void performTest() throws Exception { PEMParser pemRd = openPEMResource("test.pem"); Object o; PEMKeyPair pemPair; KeyPair pair; while ((o = pemRd.readObject()) != null) { if (o instanceof KeyPair) { //pair = (KeyPair)o; //System.out.println(pair.getPublic()); //System.out.println(pair.getPrivate()); } else { //System.out.println(o.toString()); } } // test bogus lines before begin are ignored. pemRd = openPEMResource("extratest.pem"); while ((o = pemRd.readObject()) != null) { if (!(o instanceof X509CertificateHolder)) { fail("wrong object found"); } } // // pkcs 7 data // pemRd = openPEMResource("pkcs7.pem"); ContentInfo d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData check"); } // // ECKey // pemRd = openPEMResource("eckey.pem"); ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier)pemRd.readObject(); X9ECParameters ecSpec = ECNamedCurveTable.getByOID(ecOID); if (ecSpec == null) { fail("ecSpec not found for named curve"); } pemPair = (PEMKeyPair)pemRd.readObject(); pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair); Signature sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // ECKey -- explicit parameters // pemRd = openPEMResource("ecexpparam.pem"); ecSpec = (X9ECParameters)pemRd.readObject(); pemPair = (PEMKeyPair)pemRd.readObject(); pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair); sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // writer/parser test // KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); pair = kpGen.generateKeyPair(); keyPairTest("RSA", pair); kpGen = KeyPairGenerator.getInstance("DSA", "BC"); kpGen.initialize(512, new SecureRandom()); pair = kpGen.generateKeyPair(); keyPairTest("DSA", pair); // // PKCS7 // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(d); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData recode check"); } // OpenSSL test cases (as embedded resources) doOpenSslDsaTest("unencrypted"); doOpenSslRsaTest("unencrypted"); doOpenSslTests("aes128"); doOpenSslTests("aes192"); doOpenSslTests("aes256"); doOpenSslTests("blowfish"); doOpenSslTests("des1"); doOpenSslTests("des2"); doOpenSslTests("des3"); doOpenSslTests("rc2_128"); doOpenSslDsaTest("rc2_40_cbc"); doOpenSslRsaTest("rc2_40_cbc"); doOpenSslDsaTest("rc2_64_cbc"); doOpenSslRsaTest("rc2_64_cbc"); doDudPasswordTest("7fd98", 0, "corrupted stream - out of bounds length found"); doDudPasswordTest("ef677", 1, "corrupted stream - out of bounds length found"); doDudPasswordTest("800ce", 2, "unknown tag 26 encountered"); doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); doDudPasswordTest("41af75", 11, "unknown tag 16 encountered"); doDudPasswordTest("1704a5", 12, "corrupted stream detected"); doDudPasswordTest("1c5822", 13, "unknown object in getInstance: org.bouncycastle.asn1.DERUTF8String"); doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); doDudPasswordTest("aaf9c4d",17, "corrupted stream - out of bounds length found"); doNoPasswordTest(); // encrypted private key test InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build("password".toCharArray()); pemRd = openPEMResource("enckey.pem"); PKCS8EncryptedPrivateKeyInfo encPrivKeyInfo = (PKCS8EncryptedPrivateKeyInfo)pemRd.readObject(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); RSAPrivateCrtKey privKey = (RSAPrivateCrtKey)converter.getPrivateKey(encPrivKeyInfo.decryptPrivateKeyInfo(pkcs8Prov)); if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } // general PKCS8 test pemRd = openPEMResource("pkcs8test.pem"); Object privInfo; while ((privInfo = pemRd.readObject()) != null) { if (privInfo instanceof PrivateKeyInfo) { privKey = (RSAPrivateCrtKey)converter.getPrivateKey(PrivateKeyInfo.getInstance(privInfo)); } else { privKey = (RSAPrivateCrtKey)converter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo)privInfo).decryptPrivateKeyInfo(pkcs8Prov)); } if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } } } private void keyPairTest( String name, KeyPair pair) throws IOException { PEMParser pemRd; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPublic()); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); SubjectPublicKeyInfo pub = SubjectPublicKeyInfo.getInstance(pemRd.readObject()); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PublicKey k = converter.getPublicKey(pub); if (!k.equals(pair.getPublic())) { fail("Failed public key read: " + name); } bOut = new ByteArrayOutputStream(); pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPrivate()); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); KeyPair kPair = converter.getKeyPair((PEMKeyPair)pemRd.readObject()); if (!kPair.getPrivate().equals(pair.getPrivate())) { fail("Failed private key read: " + name); } if (!kPair.getPublic().equals(pair.getPublic())) { fail("Failed private key public read: " + name); } } private void doOpenSslTests( String baseName) throws IOException { doOpenSslDsaModesTest(baseName); doOpenSslRsaModesTest(baseName); } private void doOpenSslDsaModesTest( String baseName) throws IOException { doOpenSslDsaTest(baseName + "_cbc"); doOpenSslDsaTest(baseName + "_cfb"); doOpenSslDsaTest(baseName + "_ecb"); doOpenSslDsaTest(baseName + "_ofb"); } private void doOpenSslRsaModesTest( String baseName) throws IOException { doOpenSslRsaTest(baseName + "_cbc"); doOpenSslRsaTest(baseName + "_cfb"); doOpenSslRsaTest(baseName + "_ecb"); doOpenSslRsaTest(baseName + "_ofb"); } private void doOpenSslDsaTest( String name) throws IOException { String fileName = "dsa/openssl_dsa_" + name + ".pem"; doOpenSslTestFile(fileName, DSAPrivateKey.class); } private void doOpenSslRsaTest( String name) throws IOException { String fileName = "rsa/openssl_rsa_" + name + ".pem"; doOpenSslTestFile(fileName, RSAPrivateKey.class); } private void doOpenSslTestFile( String fileName, Class expectedPrivKeyClass) throws IOException { JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build("changeit".toCharArray()); PEMParser pr = openPEMResource("data/" + fileName); Object o = pr.readObject(); if (o == null || !((o instanceof PEMKeyPair) || (o instanceof PEMEncryptedKeyPair))) { fail("Didn't find OpenSSL key"); } KeyPair kp = (o instanceof PEMEncryptedKeyPair) ? converter.getKeyPair(((PEMEncryptedKeyPair)o).decryptKeyPair(decProv)) : converter.getKeyPair((PEMKeyPair)o); PrivateKey privKey = kp.getPrivate(); if (!expectedPrivKeyClass.isInstance(privKey)) { fail("Returned key not of correct type"); } } private void doDudPasswordTest(String password, int index, String message) { // illegal state exception check - in this case the wrong password will // cause an underlying class cast exception. try { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build(password.toCharArray()); PEMParser pemRd = openPEMResource("test.pem"); Object o; while ((o = pemRd.readObject()) != null) { if (o instanceof PEMEncryptedKeyPair) { ((PEMEncryptedKeyPair)o).decryptKeyPair(decProv); } } fail("issue not detected: " + index); } catch (IOException e) { if (e.getCause() != null && !e.getCause().getMessage().endsWith(message)) { fail("issue " + index + " exception thrown, but wrong message"); } else if (e.getCause() == null && !e.getMessage().equals(message)) { e.printStackTrace(); fail("issue " + index + " exception thrown, but wrong message"); } } } private void doNoPasswordTest() throws IOException { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build("".toCharArray()); PEMParser pemRd = openPEMResource("smimenopw.pem"); Object o; PrivateKeyInfo key = null; while ((o = pemRd.readObject()) != null) { key = (PrivateKeyInfo)o; } if (key == null) { fail("private key not detected"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ParserTest()); } } 

Bene, il mio codice è come il tuo, con piccole differenze …

 public static X509Certificate loadPublicX509(String fileName) throws GeneralSecurityException { InputStream is = null; X509Certificate crt = null; try { is = fileName.getClass().getResourceAsStream("/" + fileName); CertificateFactory cf = CertificateFactory.getInstance("X.509"); crt = (X509Certificate)cf.generateCertificate(is); } finally { closeSilent(is); } return crt; } public static PrivateKey loadPrivateKey(String fileName) throws IOException, GeneralSecurityException { PrivateKey key = null; InputStream is = null; try { is = fileName.getClass().getResourceAsStream("/" + fileName); BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuilder builder = new StringBuilder(); boolean inKey = false; for (String line = br.readLine(); line != null; line = br.readLine()) { if (!inKey) { if (line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")) { inKey = true; } continue; } else { if (line.startsWith("-----END ") && line.endsWith(" PRIVATE KEY-----")) { inKey = false; break; } builder.append(line); } } // byte[] encoded = DatatypeConverter.parseBase64Binary(builder.toString()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); KeyFactory kf = KeyFactory.getInstance("RSA"); key = kf.generatePrivate(keySpec); } finally { closeSilent(is); } return key; } public static void closeSilent(final InputStream is) { if (is == null) return; try { is.close(); } catch (Exception ign) {} } 

Penso che nella tua definizione di chiave privata, dovresti sostituire:

  X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded); 

con:

  PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded); 

Guarda il tuo comando openssl :

 $openssl **pkcs8** -topk8 -inform PEM -outform PEM -in mykey.pem \ -out private_key.pem -nocrypt 

E l’eccezione java:

 Only PCKS8 codification 

Java 9+:

 private byte[] loadPEM(String resource) throws IOException { URL url = getClass().getResource(resource); InputStream in = url.openStream(); String pem = new String(in.readAllBytes(), ISO_8859_1); Pattern parse = Pattern.compile("(?m)(?s)^---*BEGIN.*---*$(.*)^---*END.*---*$.*"); String encoded = parse.matcher(pem).replaceFirst("$1"); return Base64.getMimeDecoder().decode(encoded); } @Test public void test() throws Exception { KeyFactory kf = KeyFactory.getInstance("RSA"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); PrivateKey key = kf.generatePrivate(new PKCS8EncodedKeySpec(loadPEM("test.key"))); PublicKey pub = kf.generatePublic(new X509EncodedKeySpec(loadPEM("test.pub"))); Certificate crt = cf.generateCertificate(getClass().getResourceAsStream("test.crt")); } 

Java 8:

sostituire la chiamata in.readAllBytes() con una chiamata a questo:

 byte[] readAllBytes(InputStream in) throws IOException { ByteArrayOutputStream baos= new ByteArrayOutputStream(); byte[] buf = new byte[1024]; for (int read=0; read != -1; read = in.read(buf)) { baos.write(buf, 0, read); } return baos.toByteArray(); } 

grazie a Daniel per aver notato problemi di compatibilità con API

Le librerie Java lo rendono quasi un unico strumento per leggere il certificato pubblico, come generato da openssl:

 val certificate: X509Certificate = ByteArrayInputStream( publicKeyCert.toByteArray(Charsets.US_ASCII)) .use { CertificateFactory.getInstance("X.509") .generateCertificate(it) as X509Certificate } 

Ma, diavolo, leggere la chiave privata era problematico:

  1. Prima dovevo rimuovere i tag begin e end, che non è nessarry durante la lettura della chiave pubblica.
  2. Poi ho dovuto rimuovere tutte le nuove linee, altrimenti gracchia!
  3. Poi ho dovuto decodificare in byte usando il byte 64
  4. Quindi sono stato in grado di produrre una RSAPrivateKey .

vedi questo: soluzione finale in kotlin