PDFのAES暗号化
パッケージJava製品開発担当の大です。こんにちは。
今回は、シーオーリポーツ for Java Ver.2で実装された、PDFのAES暗号化機能について書こうと思います。
以前のバージョンのシーオーリポーツ for Javaでは、PDFの暗号化アルゴリズムはRC4(40bit および 128bit)しか対応していませんでした。PDFの仕様としては、RC4に加え、PDF 1.6(AdobeReader 7)以降で128bit AESが、PDF 1.7 Adobe Extension Level 3(AdobeReader 9)以降で256bit AESが使用可能になっていたため、今回のバージョンアップでこれらに対応したという形になります。
AES暗号化対応の必要性
私も詳しく知らないのですが、平成15年に発表された電子政府推奨暗号リストでは、40bit RC4は対象外、128bit RC4も「条件つきで許可」ぐらいの扱いで、あまり積極的に推奨されていないようです。条件とは以下のようなものです(リンク先PDFより引用)。
128-bit RC4は、SSL3.0/TLS1.0以上に限定して利用することを想定している。なお、リストに掲載されている別の暗号が利用できるのであれば、そちらを使用することが望ましい。
一方、AESはこのリストでも推奨されていますし、もともとアメリカの次世代の暗号化標準(Advanced Encryption Standard)として公募されたという経緯もあり、欧州連合の暗号規格(NESSIE)でも、AES(Rijndael)が採用されているそうです。
電子政府推奨暗号リストは、現在改訂のため新しい暗号が公募されているようですが、さしあたって公的な文書の暗号化はRC4よりAESを使用しておくのが無難なようですね。
シーオーリポーツ for Java Ver.2でAES暗号化を使用する
シーオーリポーツ for Java Ver.2でAES暗号化を使用するには、暗号化の種類をAES_128
またはAES_256
で指定します。
// ドキュメントタイプとファイル名を指定してジョブを作成します CrFileOutJob job = new CrFileOutJob(CorDocumentType.PDF, "sample.pdf"); // ドキュメントを取得します CrPdfDocument doc = job.getDocument(); // セキュリティパスワードを設定して暗号化します doc.setSecurityPassword("password1"); // オープンパスワードを設定します doc.setOpenPassword("password2"); // 暗号化の種類を設定します doc.setCryptoType(CorPdfCryptoType.AES_128); // 権限を設定します doc.setAccessFlags(EnumSet.of(CorPdfAccessFlags.ALLOW_PRINTING, CorPdfAccessFlags.ALLOW_COPYING, CorPdfAccessFlags.ALLOW_SCREEN_READERS)); // ジョブを開始します job.start(draw);
ただし、このまま実行すると、(たぶん)例外が発生します。日本国内でダウンロードしたJDK/JREには、米国の輸出規制により制限がかけられているからです。
制限を解除するには、JDKのダウンロードページに行って「無制限強度の管轄ポリシーファイル」をダウンロードして設定します。
ダウンロードしたファイルを解凍すると、「local_policy.jar
」「US_export_policy.jar
」という二つのjarファイルが入っていますので、これらを%JAVA_HOME%/jre/lib/security
以下の同名のファイルと置き換えてください。
ユニコードパスワード
暗号化の種類で256bit AESを選択した場合、パスワード文字列にユニコード文字列が使用できます。たとえば、「あいうえお
」などの日本語の文字列もパスワードとして使用することができます。使用する場合は事前にSASLprep処理しておく必要があります。
例えば、オープンソースのICU4Jライブラリを使用してSASLprep処理を行う場合、以下のように記述します。
String securityPassword = "ABC"; String openPassword = "あいうえお"; // SASLprepのインスタンスを取得します StringPrep sasl = StringPrep.getInstance(StringPrep.RFC4013_SASLPREP); // セキュリティパスワードをSASLprep処理します securityPassword = sasl.prepare(securityPassword, StringPrep.DEFAULT); // オープンパスワードをSASLprep処理します openPassword = sasl.prepare(openPassword, StringPrep.DEFAULT); // セキュリティパスワードに半角の「ABC」が設定されます doc.setSecurityPassword(securityPassword); // オープンパスワードに「あいうえお」が設定されます doc.setOpenPassword(openPassword);
SASLprep処理後、全角「ABC
」が半角「ABC
」に変換されていることに注意してください。
このPDFは、AdobeReader等のビュアーのパスワードダイアログに「ABC
」「ABC
」「あいうえお
」のいずれかを入力することで開くことができます。ただし、AdobeReaderの現在の最新のバージョンでも、パスワードダイアログでIMEが有効にならないため、ひらがなを入力する場合は他のエディタ等で書いてコピー&ペーストする必要がありますが。。。
注意事項
256bit AESで暗号化されたPDFは、まだ対応していないPDFビュアーも多いため、採用には注意が必要です。想定される帳票の利用シーンに合わせて、128bit AESと256bit AESを適宜使い分けていただくと良いと思います。