2017-06-21 41 views
5

Biorąc pod uwagę to .pem plik (generowane z OpenSSL i szyfrowane za pomocą hasła):Get PrivateKey od A RSA pliku .pem

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

2wegzxf3MtncXS1CY3c..... 
.... 
.... 
-----END RSA PRIVATE KEY----- 

Jak mogę dostać PrivateKey obiektu w Java? Napisałem następujący kod, ale nie mogę znaleźć właściwą drogę, aby uzyskać 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; 
} 

Chyba powinienem zbudować RSAPrivateKeySpec, ale nie wiem jak. Próbowałem metody z this answer i this other answer, ale obaj powodują błędy podczas analizowania tablicy bajtów.

Odpowiedz

5

Używam BouncyCastle 1,57 (bcprov-jdk15on, bcmail-jdk15on i bcpkix-jdk15on) i Java 7.

Możesz przeczytać klucz prywatny, korzystając z klasy JcaPEMKeyConverter. poniżej Kod działa na klucze z i bez podawania hasła:

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

klasie privateKey „s będzie java.security.spec.RSAPrivateCrtKeySpec (która rozciąga RSAPrivateKeySpec).

4

Użyj zależności zależnej od Bouncy Castle: bcpkix, która wie, jak obsługiwać klucze OpenSSL.

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

i spróbować tak:

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

Witam, Pobieranie NPE podczas odczytu klucza prywatnego z pliku pfx chronionego hasłem za pomocą powyższej metody. – mahi