これを考えると.pem
ファイル(opensslで生成され、パスワードで暗号化されます):
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,AC009672952033EB
2wegzxf3MtncXS1CY3c.....
....
....
-----END RSA PRIVATE KEY-----
JavaでPrivateKey
オブジェクトを取得するにはどうすればよいですか?次のコードを記述しましたが、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;
}
RSAPrivateKeySpec
を作成する必要があると思いますが、方法がわかりません。 この回答 と この他の回答 のメソッドを試しましたが、どちらもバイト配列の解析時にエラーが発生します。
BouncyCastle 1.57(bcprov-jdk15on、bcmail-jdk15on、bcpkix-jdk15on)とJava 7を使用しています。
JcaPEMKeyConverter
クラスを使用して秘密鍵を読み取ることができます。以下のコードは、パスワードの有無にかかわらずキーに対して機能します。
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());
privateKey
のクラスはJava.security.spec.RSAPrivateCrtKeySpec
(RSAPrivateKeySpec
を拡張)になります。
OpenSSLキーの処理方法を知っているBouncyCastleのbcpkix依存関係を使用します。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk14</artifactId>
<version>1.57</version>
</dependency>
次のようにしてみてください。
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());
}