6.1.2 証明書によるセキュリティ設定(PKCS#12形式)

EncryptSetPubKeyWithPKCS12_Top

狙い・効果

証明書セキュリティPKCS#12ファイルでPDFに証明書セキュリティを設定します。

処理の概要

秘密鍵と証明書のパッケージファイルであるPKCS#12ファイルを使い、PDFに証明書セキュリティを設定します。選択できる暗号化形式はX.509ファイルと同じです。

PKCS#12ファイルを使用するためにはPKCS#12ファイルに設定されたパスワードが必要です。このパスワードはPKCS#12ファイルの作成時にファイルそのものに設定されるものです。

X.509ファイルと同じく、暗号化する際にユーザーアクセスフラグを設定し、権限を管理することができます。設定できる閲覧者の権限もX.509ファイルと同様です。

PtlRecipient.setPKCS12()で受信者クラスにPKCS#12ファイルを設定します。

証明書セキュリティの設定以外の操作はX.509形式と共通です。

サンプルプログラムでは、入力PDFに対して次のようにセキュリティ設定します。

  1. 指定したPKCS#12ファイルを用いてセキュリティを設定します。
  2. PKCS#12ファイルに設定されたパスワードを引数で指定します。
  3. プログラム実行時に上述の権限を引数で指定します。

『PDF Tool API』の主な機能

プログラム例

package cookbook;

import java.io.*;
import jp.co.antenna.ptl.*;

public class EncryptSetPubKeyWithPKCS12 {

    // そのクラスのusageを表示する関数
    private static void printUsage() {
            System.out.print("usage: java EncryptSetPubKeyWithPKCS12 in-pdf-file out-pdf-file ");
            System.out.println("暗号化種類 PKCS12Pubkey-path password 印刷権限種類 変更権限 コピー可否 "
							 + "アクセシビリティ有効の可否");
            System.out.println("暗号化種類");
            System.out.println("0 : 128 bit RC4  1 : 128 bit AES  2 : 256 bit AES");
	        System.out.println("印刷権限種類\n0 : 印刷不可  1 : 低解像度で可  2 : 高解像度で可");
			System.out.println("変更権限種類");			
			System.out.println("0 : 許可しない");
	        System.out.println("1 : 注釈の作成、フォームフィールドの入力と既存の署名フィールドに署名を許可");
		    System.out.println("2 : ページの挿入、削除、回転を許可");
			System.out.println("3 : フォームフィールドの入力と既存の署名フィールドに署名を許可");
		    System.out.println("4 : ページ抽出を除く全ての動作を許可");
			System.out.println("コピー可否\n0 : コピーを許可しない 1 : コピーを許可する");			
	        System.out.println("アクセシビリティの可否");
			System.out.print("(スクリーンリーダーデバイスのテキストアクセス)を");
		    System.out.println("有効にするか");
			System.out.println("0 : 有効にしない 1 : 有効にする");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 8) {
            printUsage();
            return;
        }

        // コマンドライン引数の取得
        int kind;
		String permPrint="";
		String permModify="";
		boolean permCopy;
		boolean permAccessibility;


		try {
            kind =  Integer.parseInt(args[2]);
            switch (kind) {
            case 0:
            case 1:
            case 2:
                break;
            default:
                System.out.println("暗号化種類には、0から2の数値を指定してください。");
                printUsage(); // usageメッセージの表示
                return;
            }
        }
        catch(NumberFormatException numfe) {
            System.out.println("ERROR!!暗号化種類の文字形式が正しくありません。");
            System.out.println("暗号化種類には、0から2の数値を指定してください。");
            numfe.printStackTrace();
            printUsage(); // usageメッセージの表示
            return;
        }

		//印刷権限種類
		try {
			permPrint = setPrintForPermType2(args[5]);
		}
		catch (IllegalArgumentException ex) {
            System.out.println(ex.getMessage());
            printUsage(); // usageメッセージの表示
            return;
        }

		//変更権限種類
		try {
			permModify = setModifyForPermType2(args[6]);
		}
		catch (IllegalArgumentException ex) {
            System.out.println(ex.getMessage());
            printUsage(); // usageメッセージの表示
            return;
        }

		//コピー可否
        try {
            permCopy = readBoolArgs(args[7],
										 "コピー可否は" +
                                           "0か1で指定してください。");
        }
        catch (IllegalArgumentException ex) {
            System.out.println(ex.getMessage());
            printUsage(); // usageメッセージの表示
            return;
        }

        try {
            permAccessibility = readBoolArgs(args[8],
										 "アクセシビリティ有効の可否は、" +
                                           "0か1で指定してください。");
        }
        catch (IllegalArgumentException ex) {
            System.out.println(ex.getMessage());
            printUsage(); // usageメッセージの表示
            return;
        }		


        try (PtlParamInput inputFile = new PtlParamInput(args[0]);
             PtlParamOutput outputFile = new PtlParamOutput(args[1]);
             PtlParamInput pkcs12Pubkey = new PtlParamInput(args[3]);
             PtlPDFDocument doc = new PtlPDFDocument()) {
            String password = "";
            if (args.length >= 5) {
                password = (String)args[4];
            }

            // PDFファイルをロードします
            doc.load(inputFile);

            // PDFにPKCS#12形式の証明書を設定します
            switch (kind) {
            case 0:
                // 128 bit RC4
                System.out.println("128bit RC4で暗号化します。");
                encryptPKCS12Pubkey128RC4(doc, pkcs12Pubkey, password, permPrint, permModify, permCopy, permAccessibility);
                break;
            case 1:
                // 128 bit AES
                System.out.println("128bit AESで暗号化します。");
                encryptPKCS12Pubkey128AES(doc, pkcs12Pubkey, password, permPrint, permModify, permCopy, permAccessibility);
                break;
            case 2:
                // 256 bit AES
                System.out.println("256bit AESで暗号化します。");
                encryptPKCS12Pubkey256AES(doc, pkcs12Pubkey, password, permPrint, permModify, permCopy, permAccessibility);
                break;
            }

            // ファイルに保存します
            doc.save(outputFile);
        }
	...【GetPDFVersion.javaと同じ処理のため省略
	   ・エラーメッセージ処理と出力】...
    }


    private static void encryptPKCS12Pubkey128RC4(PtlPDFDocument doc, PtlParamInput pkcs12Pubkey,
                                                  String password, String permPrint, String permModify,
                                                  boolean permCopy, boolean permAccessibility)
            throws PtlException, IOException, Exception, Error {
        try(PtlEncryptPubKey128RC4 encPubkey128RC4 = new PtlEncryptPubKey128RC4()) {//256ビットAES暗号化された公開キーセキュリティハンドラを表すクラス
            encryptPKCS12Pubkey(doc, pkcs12Pubkey, encPubkey128RC4, password, permPrint, permModify, permCopy, permAccessibility);
        }
    }    

    private static void encryptPKCS12Pubkey128AES(PtlPDFDocument doc, PtlParamInput pkcs12Pubkey,
                                                  String password, String permPrint, String permModify,
                                                  boolean permCopy, boolean permAccessibility)
            throws PtlException, IOException, Exception, Error {
        try(PtlEncryptPubKey128AES encPubkey128AES = new PtlEncryptPubKey128AES()) {//256ビットAES暗号化された公開キーセキュリティハンドラを表すクラス
            encryptPKCS12Pubkey(doc, pkcs12Pubkey, encPubkey128AES, password, permPrint, permModify, permCopy, permAccessibility);
        }
    }    

    private static void encryptPKCS12Pubkey256AES(PtlPDFDocument doc, PtlParamInput pkcs12Pubkey,
                                                  String password, String permPrint, String permModify,
                                                  boolean permCopy, boolean permAccessibility)
            throws PtlException, IOException, Exception, Error {
        try(PtlEncryptPubKey256AES encPubkey256AES = new PtlEncryptPubKey256AES()) {//256ビットAES暗号化された公開キーセキュリティハンドラを表すクラス
            encryptPKCS12Pubkey(doc, pkcs12Pubkey, encPubkey256AES, password, permPrint, permModify, permCopy, permAccessibility);
        }
    }


    private static void encryptPKCS12Pubkey(PtlPDFDocument doc, PtlParamInput pkcs12Pubkey,
                                            PtlEncryptPubKey encPubkey, String password, String permPrint, String permModify,
                                            boolean permCopy, boolean permAccessibility)
            throws PtlException, IOException, Exception, Error {
        try(PtlRecipients recipients = encPubkey.getRecipients();   //証明書受信者のコンテナを表したクラス
            PtlRecipient recipient = new PtlRecipient();            //証明書の受信者を表したクラス
            PtlEncryptPermissionPubKey permission = new PtlEncryptPermissionPubKey()) {
            //受信者クラスにPKCS#12形式の証明書を設定
            recipient.setPKCS12(pkcs12Pubkey, password);
            //受信者クラスにユーザーアクセス許可フラグを設定
            // 印刷権限の設定
            // PERM_PRINT_NOT_ALLOWED : 許可しない
            permission.setPrint(PtlEncryptPermissionType2.PERMISSION_PRINT.valueOf(permPrint));

			// 変更権限の設定
            // PERM_MODIFY_NOT_ALLOWED : 許可しない
            permission.setModify(PtlEncryptPermissionType2.PERMISSION_MODIFY.valueOf(permModify));

            // テキスト、画像、その他の内容のコピーを有効にするかどうかの設定
            // false : 有効にしない
            permission.setCopy(permCopy);

            // スクリーンリーダーデバイスのテキストアクセスを有効にするかどうかの設定
            // false : 有効にしない
            permission.setAccessibility(permAccessibility);
			//設定したユーザーアクセスフラグを設定する
            recipient.setPermission(permission);

            //受信者コンテナのクラスに受信者クラスを追加
            recipients.append(recipient);

            //以下は標準セキュリティハンドラと共通の設定
            //すべてのコンテンツを暗号化する
            encPubkey.setEncryptComponent(PtlEncrypt.ENCRYPT_COMPONENT.ENCRYPT_ALL);

            // 設定したセキュリティハンドラを用いてPDFを暗号化
            doc.setEncrypt(encPubkey);
        }
    }


    public static String setPrintForPermType2(String permPrintArg)
        throws IllegalArgumentException	{
	...【EncryptSetPubKeyWithX509.javaと同じ処理のため省略
	   ・印刷権限を表す列挙型定数名を指定をする関数】...
	}


    public static String setModifyForPermType2(String permModifyArg)
        throws IllegalArgumentException {
	...【EncryptSetPubKeyWithX509.javaと同じ処理のため省略
	   ・変更権限を表す列挙型定数名を指定をする関数】...
    }


    /**
     * 0または1を入力されたargsにより、trueまたはfalseを返すメソッド。
     * 
     * @param args 与えられるコマンドライン引数。0または1でtrueまたはfalseを指定する。
     * @param errorMessage argsが0か1でなかった場合に出力されるエラーメッセージを指定する。
     * @return argsの数値を読み取った結果を戻す
     * @throws java.lang.IllegalArgumentException argsが0か1でなかった場合に発生。
     */
    public static boolean readBoolArgs(String args, String errorMessage)
        throws IllegalArgumentException {
	...【FixUpPDFASetSaveOption.javaと同じ処理のため省略
	   ・0または1を読み取り、boolean型のfalseまたはtrueを返す関数】...
    }
}

プログラムファイル名

EncryptSetPubKeyWithPKCS12.java

入出力操作の例

C:\samples>java cookbook.EncryptSetPubKeyWithPKCS12 
usage: java EncryptSetPubKeyWithPKCS12 in-pdf-file out-pdf-file 暗号化種類 PKCS12Pubkey-path password 印刷権限種類 変更権限 コピー可否 アクセシビリティ有効の可否
暗号化種類
0 : 128 bit RC4  1 : 128 bit AES  2 : 256 bit AES
印刷権限種類
0 : 印刷不可  1 : 低解像度で可  2 : 高解像度で可
変更権限種類
0 : 許可しない
1 : 注釈の作成、フォームフィールドの入力と既存の署名フィールドに署名を許可
2 : ページの挿入、削除、回転を許可
3 : フォームフィールドの入力と既存の署名フィールドに署名を許可
4 : ページ抽出を除く全ての動作を許可
コピー可否
0 : コピーを許可しない 1 : コピーを許可する
アクセシビリティの可否
(スクリーンリーダーデバイスのテキストアクセス)を有効にするか
0 : 有効にしない 1 : 有効にする

C:\samples>java cookbook.EncryptSetPubKeyWithPKCS12 testPages_10.pdf Output_EncryptSetPubKeyWithPKCS12.pdf 2 testPKCS12.pfx testtest 0 0 1 0 
256bit AESで暗号化します。
-- 完了 --

暗号化された出力PDFを閲覧するには、暗号化に使用したPKCS#12ファイルとPKCS#12ファイルに設定したパスワードによる認証が必要です(図 6.3)。サンプルに添付のPKSC#12ファイルのパスワードは“testtest”です。認証画面はX.509ファイルでセキュリティを設定したものと同様です。

5-6-1-1_EncryptSetPubKeyWithX509_01

図6.3 証明書セキュリティ設定済みのPDFを開く際に求められる認証の例(Adobe Acrobat表示例)

また、PDFの権限設定はコピーとスクリーンリーダーのアクセス(アクセシビリティ向けのテキスト読み取り)を許可、それ以外を全て不許可にしています。

5-6-1-2_EncryptSetPubKeyWithPKCS12_02

図6.4 コピーのみを許可した場合の権限の例