PGP覚書

PGP (Pretty Good Privacy) とは

Philip Zimmermann氏が開発した暗号化ソフトとその規格。
電子メールやファイルの暗号化や電子署名に用いられる。
公開鍵暗号方式を採用し、秘密鍵と公開鍵を用いてそれぞれ暗号化と署名を行う。

JavaPGP

Bouncy Castle Crypto APIs : 暗号化ライブラリ
http://www.bouncycastle.org/

bcprov-jdkxx-xxx.jar
bcpg-jdkxx-xxx.jar
をダウンロードする。

/**
 * ファイルを暗号化する
 * 
 * @param clearTextFile 平文ファイル
 * @param encryptFile 暗号化ファイル
 * @param secringgpg GnuPGの鍵が保存されているsecring.gpg
 * @throws GeneralSecurityException
 * @throws IOException
 * @throws PGPException
 */
public void encryptFile(File clearTextFile, File encryptFile, File secringgpg)
		throws GeneralSecurityException, IOException, PGPException {
	installBC();
	byte[] data = encrypt(getPublicKey(secringgpg), clearTextFile);
	createFile(data, encryptFile);
}

/**
 * ファイルを複合する
 * 
 * @param encryptFile 暗号化ファイル
 * @param clearTextFile 平文ファイル
 * @param secringgpg GnuPGの鍵が保存されているsecring.gpg
 * @param passphrase パスフレーズ
 * @throws GeneralSecurityException
 * @throws IOException
 * @throws PGPException
 */
public void decryptFile(File encryptFile, File clearTextFile, File secringgpg, char[] passphrase)
		throws GeneralSecurityException, IOException, PGPException {
	installBC();
	byte[] data = decrypt(getPrivateKey(secringgpg, passphrase), encryptFile);
	createFile(data, clearTextFile);
}

private void installBC() {
	if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
		Security.addProvider(new BouncyCastleProvider());
	}
}

private byte[] encrypt(Key key, File clearTextFile) throws GeneralSecurityException, IOException {
	byte[] data = getByteData(clearTextFile);
	Cipher cipher = Cipher.getInstance("RSA", Security.getProvider(BouncyCastleProvider.PROVIDER_NAME));
	cipher.init(Cipher.ENCRYPT_MODE, key);
	cipher.update(data);
	return cipher.doFinal();
}

private byte[] decrypt(Key key, File encryptFile) throws GeneralSecurityException, IOException {
	byte[] data = getByteData(encryptFile);
	Cipher cipher = Cipher.getInstance("RSA", Security.getProvider(BouncyCastleProvider.PROVIDER_NAME));
	cipher.init(Cipher.DECRYPT_MODE, key);
	cipher.update(data);
	return cipher.doFinal();
}

private PrivateKey getPrivateKey(File secringgpg, char[] passphrase)
		throws NoSuchProviderException, PGPException, IOException {
	PGPPrivateKey pgpPrivateKey = getSecretKey(secringgpg).extractPrivateKey(
			passphrase, BouncyCastleProvider.PROVIDER_NAME);
	return pgpPrivateKey.getKey();
}

private PublicKey getPublicKey(File secringgpg) throws NoSuchProviderException, IOException, PGPException {
	PGPPublicKey pgpPublicKey = getSecretKey(secringgpg).getPublicKey();
	PublicKey publicKey = pgpPublicKey.getKey(BouncyCastleProvider.PROVIDER_NAME);
	return publicKey;
}

private PGPSecretKey getSecretKey(File secringgpg) throws IOException, PGPException {
	InputStream is = null;
	try {
		is = PGPUtil.getDecoderStream(new FileInputStream(secringgpg));
		PGPSecretKeyRing keyRing = new PGPSecretKeyRing(is);
		return keyRing.getSecretKey();
	} finally {
		if (is != null) is.close();
	}
}

private byte[] getByteData(File file) throws IOException {
	FileInputStream fis = null;
	try {
		fis = new FileInputStream(file);
		byte[] fileData = new byte[(int) file.length()];
		fis.read(fileData);
		return fileData;
	} finally {
		if (fis != null) fis.close();
	}
}

private void createFile(byte[] fileData, File file) throws IOException {
	if (file.exists()) file.delete();
	
	FileOutputStream fos = null;
	try {
		fos = new FileOutputStream(file);
		fos.write(fileData);
	} finally {
		if (fos != null) fos.close();
	}
}