Get PrivateKey from RSA.pem file

Given this .pem file (generated using openssl and encrypted with a password):

 -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,AC009672952033EB 2wegzxf3MtncXS1CY3c..... .... .... -----END RSA PRIVATE KEY----- 

How do I get a PrivateKey object in Java? I wrote the following code, but cannot find the correct way to get KeySpec :

 PrivateKey readFromPem(File keyFile, String password){ PemReader r = new PemReader(new InputStreamReader(new FileInputStream(keyFile))); PemObject pemObject = r.readPemObject(); byte[] encodedKey = pemObject.getContent(); KeySpec keySpec = ???? // how to get this? KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey key = keyFactory.generatePrivate(keySpec); return key; } 

I think I should build RSAPrivateKeySpec , but I do not know how to do this. I tried the method this answer and this other answer , but both of them lead to errors when parsing the byte array.

+5
source share
2 answers

I am using BouncyCastle 1.57 (bcprov-jdk15on, bcmail-jdk15on and bcpkix-jdk15on) and Java 7 .

You can read the private key using the JcaPEMKeyConverter class. The code below works for keys with and without a password:

 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.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; // don't forget to add the provider Security.addProvider(new BouncyCastleProvider()); String password = "your password"; // reads your key file PEMParser pemParser = new PEMParser(new FileReader(keyFile)); Object object = pemParser.readObject(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); KeyPair kp; if (object instanceof PEMEncryptedKeyPair) { // Encrypted key - we will use provided password PEMEncryptedKeyPair ckp = (PEMEncryptedKeyPair) object; // uses the password to decrypt the key PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray()); kp = converter.getKeyPair(ckp.decryptKeyPair(decProv)); } else { // Unencrypted key - no password needed PEMKeyPair ukp = (PEMKeyPair) object; kp = converter.getKeyPair(ukp); } // RSA KeyFactory keyFac = KeyFactory.getInstance("RSA"); RSAPrivateCrtKeySpec privateKey = keyFac.getKeySpec(kp.getPrivate(), RSAPrivateCrtKeySpec.class); System.out.println(privateKey.getClass()); 

The privateKey class will be java.security.spec.RSAPrivateCrtKeySpec (which extends RSAPrivateKeySpec ).

+5
source

Use the bcpkix dependency on Bouncy Castle, which knows how to handle OpenSSL keys.

 <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk14</artifactId> <version>1.57</version> </dependency> 

and try to do it like this:

 private PrivateKey readFromPem(File keyFile, String password) throws IOException { Security.addProvider(new BouncyCastleProvider()); PEMParser pemParser = new PEMParser(new InputStreamReader(new FileInputStream(keyFile))); PEMEncryptedKeyPair encryptedKeyPair = (PEMEncryptedKeyPair) pemParser.readObject(); PEMDecryptorProvider decryptorProvider = new JcePEMDecryptorProviderBuilder().build(password.toCharArray()); PEMKeyPair pemKeyPair = encryptedKeyPair.decryptKeyPair(decryptorProvider); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); return converter.getPrivateKey(pemKeyPair.getPrivateKeyInfo()); } 
+4
source

Source: https://habr.com/ru/post/1269073/


All Articles