Bouncy Castleを利用してOpenSSLで生成したPEM形式のファイルを読み込む

今回はOpenSSLで秘密鍵や公開鍵等を生成したときのデフォルトのフォーマットであるPEM形式のファイルをJavaから読み込んで見たいと思います。

OepnSSLで秘密鍵、公開鍵を作成する

サンプルで利用する秘密鍵、公開鍵を作成しておきます。

#[秘密鍵]
openssl genrsa -out rs256.key 2048
#[公開鍵]
openssl rsa -pubout < rs256.key > rs256.pub.key
#上記生成した秘密鍵をpkcs#8へ変換する
openssl pkcs8 -in rs256.key -out rs256.key.pkcs8 -topk8 -nocrypt

Bouncy Castleの依存性を追加する

オープンソースの暗号化ライブラリであるBouncy Castleの依存性を追加します。
Mavenを利用している場合、pomファイルに以下の記述を追加します。

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
<dependency>
	<groupId>org.bouncycastle</groupId>
	<artifactId>bcpkix-jdk15on</artifactId>
	<version>1.50</version>
</dependency>

サンプルソース

やっていることはPEMParserに作成しておいた公開鍵を読み込ませて、変換後の型にキャストしているだけです。
サンプルでは公開鍵を読み込ませていますが、秘密鍵や証明書でも同じようにできます。

public class PEMParserSample {

	// BouncyCastleがセキュリティプロバイダに登録されていない場合、
	// JcaPEMKeyConverter#setProvider(java.lang.String providerName)を
	// JcaPEMKeyConverter conv = new
	// JcaPEMKeyConverter().setProvider("BC");のようにコールすると
	// 「Caused by: java.security.NoSuchProviderException: no such provider:
	// BC」の例外が発生する
	//
	// 回避方法
	// 1.policyファイルにBouncyCastleを追加
	// security.provider.5=org.bouncycastle.jce.provider.BouncyCastleProvider
	// 2.プログラム上で追加
	// Security.addProvider(new BouncyCastleProvider());
	//
	// ここではJcaPEMKeyConverter#setProvider(java.security.Provider
	// provider)でセキュリティプロバイダを指定している
	private static final JcaPEMKeyConverter conv = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider());

	public static void main(String[] args) {
		PublicKey publicKey = pemToPublicKey("rs256.pub.key");
	}

	public static PublicKey pemToPublicKey(String publicKeyFilePath) {
		PublicKey publicKey = null;

		// PEM形式の公開鍵ファイルからPublicKeyを生成する
		try (PEMParser parser = new PEMParser(
				new InputStreamReader(ClassLoader.getSystemResourceAsStream(publicKeyFilePath)))) {
			Object obj = parser.readObject();
			if (obj instanceof SubjectPublicKeyInfo) {
				SubjectPublicKeyInfo keyInfo = (SubjectPublicKeyInfo) obj;
				publicKey = conv.getPublicKey(keyInfo);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return publicKey;
	}

}