6.1.1 証明書によるセキュリティ設定(X.509形式)

EncryptSetPubKeyWithX509_Top

狙い・効果

証明書セキュリティX.509形式の証明書でPDFにセキュリティを設定します。

処理の概要

X.509形式の証明書でPDFにセキュリティを設定できます。

選択できる暗号化形式は次の3つです。

セキュリティ設定では、暗号化する際にユーザーアクセスフラグを設定することができます。ユーザーアクセスフラグで閲覧者の権限を管理します。

設定できる権限は次の通りです。

  1. 受信者クラスにPtlRecipient.setX509() でX.509 証明書ファイルの設定をし、87PtlRecipient.setPermission() でユーザーアクセスフラグの設定をします。
  2. PtlRecipients.append() を用いて証明書コンテナに証明書のクラスを追加し、PDFに証明書セキュリティを設定します。証明書コンテナには複数の証明書クラスを登録することも可能です。

サンプルプログラムでは、入力PDFに対して、指定したX.509証明書を用いてセキュリティを設定します。プログラム実行時に上述の権限を引数で指定します。

『PDF Tool API』の主な機能

表6.2 暗号化の種類
暗号化の種類 暗号化種別に対応した子クラス
128ビットAES
PtlEncryptPubKey128AES
128ビットRC4
PtlEncryptPubKey128RC4
256ビットAES
PtlEncryptPubKey256AES

表6.3 PtlEncryptPermissionType2.PERMISSION_MODIFYが表す変更権限
列挙型定数 説明
PERM_MODIFY_ANNOTANDFORM注釈の作成、フォームフィールドの入力と既存の署名フィールドに署名 権限フラグの6,9ビット目をOn
PERM_MODIFY_ASSEMBLEDOCページの挿入、削除、回転 権限フラグの11ビット目をOn
PERM_MODIFY_FILLFORMフォームフィールドの入力と既存の署名フィールドに署名 権限フラグの9ビット目をOn
PERM_MODIFY_MODYFYDOCページ抽出を除く全ての動作 権限フラグの4,6,9ビット目をOn
PERM_MODIFY_NOT_ALLOWED許可しない
表6.4 PtlEncryptPermissionType2.PERMISSION_PRINTが表す印刷権限
列挙型定数 説明
PERM_PRINT_HIGH高解像度 権限フラグの3,12ビット目をOn
PERM_PRINT_LOW低解像度 権限フラグの3ビット目をOn
PERM_PRINT_NOT_ALLOWED許可しない
参考 *

各ユーザーアクセスフラグのビット位置の詳細は「6.1セキュリティ設定(証明キュリティ)」を参照してください。

プログラム例

package cookbook;

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

public class EncryptSetPubKeyWithX509 {

    // そのクラスのusageを表示する関数
    private static void printUsage() {
            System.out.print("usage: java EncryptSetPubKeyWithX509 in-pdf-file out-pdf-file ");
            System.out.println("暗号化種類 X509Pubkey-path 印刷権限種類 変更権限 コピー可否 "
							 + "アクセシビリティ有効の可否");
            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[4]);
		}
		catch (IllegalArgumentException ex) {
            System.out.println(ex.getMessage());
            printUsage(); // usageメッセージの表示
            return;
        }

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

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

        try {
            permAccessibility = readBoolArgs(args[7],
										 "アクセシビリティ有効の可否は、" +
                                           "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 x509Pubkey = new PtlParamInput(args[3]);
             PtlPDFDocument doc = new PtlPDFDocument()) {

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

            // PDFにX.509形式の証明書を設定します
            switch (kind) {
            case 0:
                // 128 bit RC4
                System.out.println("128bit RC4で暗号化します。");
                encryptX509Pubkey128RC4(doc, x509Pubkey, permPrint, permModify, permCopy, permAccessibility);
                break;
            case 1:
                // 128 bit AES
                System.out.println("128bit AESで暗号化します。");
                encryptX509Pubkey128AES(doc, x509Pubkey, permPrint, permModify, permCopy, permAccessibility);
                break;
            case 2:
                // 256 bit AES
                System.out.println("256bit AESで暗号化します。");
                encryptX509Pubkey256AES(doc, x509Pubkey, permPrint, permModify, permCopy, permAccessibility);
                break;
            }

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


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

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

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


    private static void encryptX509Pubkey(PtlPDFDocument doc, PtlParamInput x509Pubkey,
										  PtlEncryptPubKey encPubkey, 
                                          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()) {
            //受信者クラスにX.509形式の証明書を設定
            recipient.setX509(x509Pubkey);

            //受信者クラスにユーザーアクセス許可フラグを設定
            // 印刷権限の設定
            // 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	{
		String permPrint ="PERM_PRINT_NOT_ALLOWED";

        switch (permPrintArg) {
        case "0":
            // PERM_MODIFY_NOT_ALLOWEDを用いるため、変更無し
            break;
        case "1":
            permPrint = "PERM_PRINT_LOW";
            break;
        case "2":
            permPrint = "PERM_PRINT_HIGH";
            break;

        default:
            throw new IllegalArgumentException("印刷権限種類には、0から2の数値を指定してください。");
        }

		return permPrint;
	}


    public static String setModifyForPermType2(String permModifyArg)
        throws IllegalArgumentException {
        String permModify2 = "PERM_MODIFY_NOT_ALLOWED";
        switch (permModifyArg) {
        case "0":
            // PERM_MODIFY_NOT_ALLOWEDを用いるため、変更無し
            break;
        case "1":
            permModify2 = "PERM_MODIFY_ANNOTANDFORM";
            break;
        case "2":
            permModify2 = "PERM_MODIFY_ASSEMBLEDOC";
            break;
        case "3":
            permModify2 = "PERM_MODIFY_FILLFORM";
            break;
        case "4":
            permModify2 = "PERM_MODIFY_MODYFYDOC";
            break;
        default:
            throw new IllegalArgumentException("変更権限種類には、0から4の数値を指定してください。");
        }

        return permModify2;
    }


    /**
     * 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を返す関数】...
    }
}

プログラムファイル名

EncryptSetPubKeyWithX509.java

入出力操作の例

C:\samples>java cookbook.EncryptSetPubKeyWithX509 
usage: java EncryptSetPubKeyWithX509 in-pdf-file out-pdf-file 暗号化種類 X509Pubkey-path 印刷権限種類 変更権限 コピー可否 アクセシビリティ有効の可否
暗号化種類
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.EncryptSetPubKeyWithX509 testPages_10.pdf Output_EncryptSetPubKeyWithX509.pdf 2 antennaJirouX509.cer 0 0 0 0 
256bit AESで暗号化します。
-- 完了 --

出力されたPDFは暗号化されているため、閲覧するにはあらかじめ設定した証明書とパスワードによる認証を求められます(図 6.1)。文書に関する制限として印刷・文書の変更・コピー・アクセシビリティ向けテキスト読み取りの全てが不許可に設定されてることが確認できます(図 6.2)。

5-6-1-1_EncryptSetPubKeyWithX509_01

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

5-6-1-1_EncryptSetPubKeyWithX509_02

図6.2 証明書セキュリティの権限を制限している例