1.2.3 変更不可セキュリティの設定

images/EncryptSetModify-top.png

狙い・効果

オーナーパスワードによりPDF文書の変更に関する制限を設定します。

処理の概要

オーナーパスワードでPDF文書の変更を許可するか、しないかの設定ができます。

権限設定にはタイプ1とタイプ2があります(表1・5 権限設定のタイプを参照)。

表1・9 タイプ1の権限設定(PDF文書の変更)
列挙型定数説明
PERM_MODIFY_ANNOTANDFORM注釈の作成、フォームフィールドの入力と既存の署名フィールドに署名を許可 権限フラグの6ビット目をOn
PERM_MODIFY_ASSEMBLEANDFORMページレイアウト、フォームフィールドの入力と既存の署名フィールドに署名を許可 権限フラグの4ビット目をOn
PERM_MODIFY_MODYFYDOCページ抽出を除く全ての動作を許可 権限フラグの4,6ビット目をOn
PERM_MODIFY_NOT_ALLOWED許可しない

表1・6 ISO 32000-1 表22 ユーザーアクセス許可―タイプ1を参照

表1・10 タイプ2の権限設定(PDF文書の変更)
列挙型定数説明
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許可しない

表1・7 ISO 32000-1 表22 ユーザーアクセス許可―タイプ2を参照

本プログラム例では指定されたPDFの変更可否セキュリティを設定します。

PDF Tool APIの主な機能

プログラム例

package cookbook;

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

public class EncryptSetModify {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 3)
        {
            System.out.print("usage: java EncryptSetModify in-pdf-file out-pdf-file ");
            System.out.println("out-pdf-ownerpass [in-pdf-password]");
            return;
        }

        // コマンドライン引数の取得
        String outOwnerPass = args[2];

        ...【EncryptSetEncComponent.javaと同じ処理のため省略
             ・PtlParamInputを用いてPtlPDFDocument docに入力PDFをロード
             ・PtlParamOutputを用いて出力PDF名を指定
             ・BufferedReader brを設定してキー入力読み取りを準備する
             ・入力PDF用パスワードが指定されていればそれをセットした上でPDFをロードする】...

                // 暗号化情報の取得
                setPermModify(doc, outOwnerPass, br);
            }
            else
            {
                System.out.println("暗号化されていないファイルです。\n");
                System.out.println("変更権限を設定して暗号化します。");
                System.out.println("暗号化種類の設定をします。0から3の数値を指定してください。");
                System.out.println("それ以外の数値が設定された場合は 3 が選択されたものとして扱います。");
                System.out.println("暗号化種類");
                System.out.println("0 : 40 bit RC4  1 : 128 bit RC4  2 : 128 bit AES  3 : 256 bit AES");
                int kind = Integer.parseInt(br.readLine());
                // セキュリティ設定
                switch (kind)
                {
                case 0:
                    // 40 bit RC4
                    encrypt40RC4setModify(doc, outOwnerPass, br);
                    break;
                case 1:
                    // 128 bit RC4
                    encrypt128RC4setModify(doc, outOwnerPass, br);
                    break;
                case 2:
                    // 128 bit AES
                    encrypt128AESsetModify(doc, outOwnerPass, br);
                    break;
                case 3:
                default:
                    // 256 bit AES
                    encrypt256AESsetModify(doc, outOwnerPass, br);
                    break;
                }
            }
        ...【EncryptWithUserPass.javaと同じ処理のため省略
             ・PtlParamOutputを用いてPtlPDFDocument docの内容を出力
             ・PtlException, Exception, Error を catchするエラー処理
             ・finally文で"--完了--"と表示する処理】...
    }

    public static void encrypt40RC4setModify(PtlPDFDocument doc, String outOwnerPass, BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        // 40 bit RC4
        System.out.println("40 bit RC4暗号化が選択されました。");
        try (PtlEncryptStandard40RC4 enc40 = new PtlEncryptStandard40RC4())
        {
            setModifyWithDefaultPermission(doc, outOwnerPass, br, enc40);
        }
    }

    public static void encrypt128RC4setModify(PtlPDFDocument doc, String outOwnerPass, BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        // 128 bit RC4
        System.out.println("128 bit RC4暗号化が選択されました。");
        try (PtlEncryptStandard128RC4 enc128r = new PtlEncryptStandard128RC4())
        {
            setModifyWithDefaultPermission(doc, outOwnerPass, br, enc128r);
        }
    }

    public static void encrypt128AESsetModify(PtlPDFDocument doc, String outOwnerPass, BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        // 128 bit AES
        System.out.println("128 bit AES暗号化が選択されました。");
        try (PtlEncryptStandard128AES enc128a = new PtlEncryptStandard128AES())
        {
            setModifyWithDefaultPermission(doc, outOwnerPass, br, enc128a);
        }
    }

    public static void encrypt256AESsetModify(PtlPDFDocument doc, String outOwnerPass, BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        // 256 bit AES
        System.out.println("256 bit AES暗号化が選択されました。");
        try (PtlEncryptStandard256AES enc256 = new PtlEncryptStandard256AES())
        {
            setModifyWithDefaultPermission(doc, outOwnerPass, br, enc256);
        }
    }
    public static void setModifyWithDefaultPermission(PtlPDFDocument doc, String outOwnerPass,
                                                      BufferedReader br, PtlEncryptStandard enc)
        throws PtlException, IOException, Exception, Error
    {

        // 暗号化するコンテンツ
        // 文書の全てのコンテンツを暗号化します。
        enc.setEncryptComponent(PtlEncrypt.ENCRYPT_COMPONENT.ENCRYPT_ALL);
        // オーナーパスワード値の設定
        enc.setOwnerPassword(outOwnerPass);
        // encが40 bit RC4の場合はPtlEncryptPermissionType1を用いる必要がある
        if((enc.getMethod() == PtlEncryptStandard.STANDARD_METHOD_TYPE.METHOD_RC4) &&
           (enc.getKeyLength() == 40))
        {
            try (PtlEncryptPermissionType1 perms1 = new PtlEncryptPermissionType1())
            {
                // 変更権限の設定
                String permModify1 = setModifyForPermType1(br);
                perms1.setModify(PtlEncryptPermissionType1.PERMISSION_MODIFY.valueOf(permModify1));

                // 印刷権限の設定 true : 印刷を許可する
                perms1.setPrint(true);
                // テキスト、画像、その他の内容のコピーおよびアクセシビリティを有効にするかどうかの設定
                // true : 有効にする
                perms1.setCopy(true);
                // ユーザアクセス許可フラグの設定
                enc.setPermission(perms1);
            }
        }
        // encが40 bit RC4以外場合はPtlEncryptPermissionType2を用いる必要がある
        else
        {
            try (PtlEncryptPermissionType2 perms2 = new PtlEncryptPermissionType2())
            {
                // 変更権限の設定
                String permModify2 = setModifyForPermType2(br);
                perms2.setModify(PtlEncryptPermissionType2.PERMISSION_MODIFY.valueOf(permModify2));

                // 印刷権限の設定 PERM_PRINT_HIGH : 高解像度での印刷を許可
                perms2.setPrint(PtlEncryptPermissionType2.PERMISSION_PRINT.PERM_PRINT_HIGH);
                // テキスト、画像、その他の内容のコピーを有効にするかどうかの設定 true: 有効にする
                perms2.setCopy(true);
                // スクリーンリーダーデバイスのテキストアクセスを有効にするかどうかの設定
                // true: 有効にする
                perms2.setAccesibility(true);

                // ユーザアクセス許可フラグの設定
                enc.setPermission(perms2);
            }
        }

        // 暗号化情報の設定
        doc.setEncrypt(enc);        
    }

    public static void setPermModify(PtlPDFDocument doc,String outOwnerPass, BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        ...【EncryptSetPrint.javaと同じ処理のため省略。
             ・PtlPDFDocument docが保持している暗号化情報PtlEncrypt encryptの取得。
             ・標準セキュリティハンドラであることを確認し、encryptをPtlEncryptStandardにダウンキャスト。
             ・出力用オーナーパスワードの設定。
             ・ユーザーアクセス許可フラグPtlEncryptPermission permsの取得】...

                    // タイプ取得
                    switch (perms.getType())
                    {
                    case PERM_TYPE1:
                        // getType()で判定されたのでpermsをダウンキャストできる。
                        PtlEncryptPermissionType1 perms1 = (PtlEncryptPermissionType1)perms;
                        // 編集権限設定
                        String permModify1 = setModifyForPermType1(br);
                        perms1.setModify(PtlEncryptPermissionType1.PERMISSION_MODIFY.valueOf(permModify1));
                        encryptStandard.setPermission(perms1);
                        break;

                    case PERM_TYPE2:
                        // getType()で判定されたのでpermsをダウンキャストできる。
                        PtlEncryptPermissionType2 perms2 = (PtlEncryptPermissionType2)perms;
                        // 編集権限設定
                        String permModify2 = setModifyForPermType2(br);
                        perms2.setModify(PtlEncryptPermissionType2.PERMISSION_MODIFY.valueOf(permModify2));
                        encryptStandard.setPermission(perms2);
                        break;
                    }
                }
         ...【EncryptSetPrint.javaと同じ処理のため省略。
             ・PtlPDFDocument docに変更したセキュリティ情報を設定。
             ・標準セキュリティハンドラ以外が与えられた際の例外処理。】...
              }
        }
    }

    public static String setModifyForPermType1(BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        System.out.println("変更権限の設定をします。以下から数値で指定してください。");
        System.out.println("これ以外の数値が指定された場合は 0 とみなされます。");
        System.out.println("0 : 許可しない");
        System.out.println("1 : 注釈の作成、フォームフィールドの入力と既存の署名フィールドに署名を許可");
        System.out.println("2 : ページレイアウト、フォームフィールドの入力と既存の署名フィールドに署名を許可");
        System.out.println("3 : ページ抽出を除く全ての動作");
        int choiceOfPerm = Integer.parseInt(br.readLine());
        String permModify1 = "PERM_MODIFY_NOT_ALLOWED";
        switch (choiceOfPerm)
        {
        case 0:
            // PERM_MODIFY_NOT_ALLOWEDを用いるため、変更無し
            break;
        case 1:
            permModify1 = "PERM_MODIFY_ANNOTANDFORM";
            break;
        case 2:
            permModify1 = "PERM_MODIFY_ASSEMBLEANDFORM";
            break;
        case 3:
            permModify1 = "PERM_MODIFY_MODYFYDOC";
            break;
        default:
            // PERM_MODIFY_NOT_ALLOWEDを用いるため、変更無し
            break;
        }        
        return permModify1;
    }

    public static String setModifyForPermType2(BufferedReader br)
        throws PtlException, IOException, Exception, Error
    {
        System.out.println("変更権限の設定をします。以下から数値で指定してください。");
        System.out.println("これ以外の数値が指定された場合は 0 とみなされます。");
        System.out.println("0 : 許可しない");
        System.out.println("1 : 注釈の作成、フォームフィールドの入力と既存の署名フィールドに署名を許可");
        System.out.println("2 : ページの挿入、削除、回転を許可");
        System.out.println("3 : フォームフィールドの入力と既存の署名フィールドに署名を許可");
        System.out.println("4 : ページ抽出を除く全ての動作を許可");

        int choiceOfPerm = Integer.parseInt(br.readLine());
        String permModify2 = "PERM_MODIFY_NOT_ALLOWED";
        switch (choiceOfPerm)
        {
        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:
            // PERM_MODIFY_NOT_ALLOWEDを用いるため、変更無し
            break;
        }        

        return permModify2;
    }
}

プログラムファイル名

EncryptSetModify.java

入出力操作の例

images/EncryptSetModify.png

最初の例は、暗号化キーの長さ40ビットRC4で、タイプ1の権限設定の変更に関する制限設定をします。

images/EncryptSetModify1.png

次は、暗号化キーの長さ128ビットRC4で、タイプ2の権限設定の変更に関する制限設定をします。

images/EncryptSetModify2.png