開発者ブログ
TOP開発者ブログPDFのAES暗号化

PDFのAES暗号化

Java 機能紹介

パッケージ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が使用可能になっていたため、今回のバージョンアップでこれらに対応したという形になります。

256bit AESで暗号化されたPDF

256bit AESで暗号化されたPDF(クリックで拡大)

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を適宜使い分けていただくと良いと思います。

帳票ツールに関するお悩みを
トータルでサポートいたします