Bouncy CastleでOpenPGP鍵を操作する
Bouncy CastleのOpenPGP用ライブラリ(bcpg)を使ってOpenPGP鍵を操作する方法のメモです。以前の日記にsecring.gpgを読み込んで利用する方法がありますので、今回はそれ以外の操作が対象です。
PGPSecretKeyを生成する
public PGPSecretKey generateSecretKey() { // JCEでの一般的な鍵生成 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // PGPSecretKeyの生成 return new PGPSecretKey( PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_SIGN, // 鍵のアルゴリズムと用途 keyPair.getPublic(), // PublicKeyとPrivateKeyの keyPair.getPrivate(), // ペアを指定 new Date(), // 鍵の生成日時 "user@example.com", // ユーザID SymmetricKeyAlgorithmTags.AES_256, // 鍵を保護する際に使用する暗号 "passphrase".toCharArray(), // 鍵を保護する際に使用するパスフレーズ null, // 鍵に付与する属性 null, // 鍵に付与する属性 new SecureRandom(), "BC");
公開鍵への署名を作成する
/** * @param targetKey 署名対象の鍵 * @param userId 署名対象のユーザID * @param signKey 署名する人の鍵 */ public PGPSignature makeSignature(PGPPublicKey targetKey, String userID, PGPPrivateKey signKey) { PGPSignatureGenerator generator = new PGPSignatureGenerator( PublicKeyAlgorithmTags.RSA_SIGN, // 署名に利用する鍵(signKey)のアルゴリズム HashAlgorithmTags.SHA256, // 署名に利用するハッシュアルゴリズム "BC"); generator.initSign(PGPSignature.CASUAL_CERTIFICATION, signKey); return generator.generateCertification(userID, targetKey); }
公開鍵に署名を追加する
先ほど作成した署名を公開鍵(PGPPublicKey)に追加する方法です。
// PGPPublicKey publicKey; // PGPSignature signature; // publicKey = PGPPublicKey.addCertification(publicKey, signature);
bcpgでは、このように既存のオブジェクトにデータを追加した新しいオブジェクトを作成するstaticなメソッドが沢山あります。例えばPGPPublicKeyRingへのPGPPublicKeyの追加も同様の方法になります。
// PGPPublicKeyRing keyRing; // PGPPublicKey publicKey; // keyRing = PGPPublicKeyRing.insertPublicKey(keyRing, publicKey);
保存と読込
バイナリ形式の場合
// PGPPublicKeyRing keyRing; // FileOutputStream fos = new FileOutputStream("pubring.gpg"); keyRing.encode(fos); fos.close();
テキスト形式の場合(テキスト形式は BEGIN PGP でおなじみのやつです。)
// PGPPublicKeyRing keyRing; // FileOutputStream fos = new FileOutputStream("pubring.gpg"); ArmoredOutputStream os = new ArmoredOutputStream(fos); keyRing.encode(os); os.close();
こちらは読込方法です。以前とあまり変わりませんが、PGPUtil.getDecoderStream()を使うことで、テキスト形式とバイナリ形式の両方に対応しています。
FileInputStream fis = new FileInputStream("secring.gpg"); InputStream is = PGPUtil.getDecoderStream(fis); // ファイル形式を判断して適切なInputStreamを返す PGPSecretKeyRing keyRing = new PGPSecretKeyRing(is); is.close();
これ以外のクラスも基本的に、encodeで保存、コンストラクタでbyte[]もしくはInputStreamから読込という形式になります。