1.Apache FOP2.0の新機能
2012/10/20 FOP1.1がリリースされて、約2年6ヶ月後の2015/06/03日に、2.0がリリースされました。
OpenTypeフォントの対応は、要望が多かったと思います。OpenTypeのみのフォントの場合、重宝しそうです。
個人的には、前々から希望していた、AES256bitの暗号化対応が、されていて、とても良かったです。これで、セキュリティがより高まったと思います。
その他の機能の詳細は、右記サイトで確認できます。 https://xmlgraphics.apache.org/fop/2.0/releaseNotes_2.0.html
JDKでAES256bitを使用する場合は、「Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy」が必要です。
下記のORACLEのURLからダウンロードできます。
JDK 7用JCE http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK 8用JCE http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
図 1. EncryptPDF.javaでは、46行目で高強度のAES 256bitを使用するようにしています。「Apache™ FOP: PDF encryption.」にて、レンダラのオプションで設定できる項目が記載されています。「fop.xconf」の設定ファイル及び、プログラム内部でパスワード等の設定ができます。文書を開くパスワードで、PDFを開いた場合と、権限パスワードで、PDFを開いた場合で、PDFの文書プロパティの「PDFの文書に関する制限の概要」に違いがあります。巷には、PDFのセキュリティを解除するソフトや、オンラインのサービスが展開されていますので、PDFのパスワードの管理はしっかりしたいところです。パスワードの長さは、8桁では数時間で解析できる環境があるので、注意が必要です。
2.フォントファミリ名設定の確認方法
フォントファミリ名を指定してあるけで、思ったとおりにフォントが出力されない場合は、初回実行時に、下記場所に、フォントキャッシュが作成されるので、%UserProfile%\.fop\fop-fonts.cache
fop-fonts.cacheをテキストエディタで開き、フォントファイル名で検索する。その後、その付近にあるフォント名を確認する。
フォントキャッシュは、削除すると自動で再作成されます。フォントのインストールした場合は、削除して再作成する必要があります。
(SyntaxHighlighterを使用して、プログラムを掲載しています。ダブルクリックで全選択されます。注意点として、「さらに記事を読み込む」のリンクで、この記事を読み込んだ場合に、SyntaxHighlighterによる表示が不正になる場合がありますので、恐れ入りますが、タイトルをクリックして再表示して下さい。)
図 1. EncryptPDF.java
package com.wordpress.okulejp.encryptpdf; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopConfParser; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.FopFactoryBuilder; import org.apache.fop.apps.MimeConstants; import org.apache.fop.pdf.PDFEncryptionParams; public class EncryptPDF { public static void main(String[] args) throws TransformerException, TransformerConfigurationException, FileNotFoundException, IOException { OutputStream out = null; try { FopConfParser fopConfParser = new FopConfParser(new File("fop.xconf")); FopFactoryBuilder fopFactoryBuilder = fopConfParser.getFopFactoryBuilder(); FopFactory fopFactory = fopFactoryBuilder.build(); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); out = new FileOutputStream("blog/encryptPDF.pdf"); out = new BufferedOutputStream(out); //セキュリティ設定 PDFEncryptionParams params = new PDFEncryptionParams(); params.setOwnerPassword("owner"); params.setUserPassword("user"); params.setAllowCopyContent(false); params.setAllowEditContent(false); params.setAllowEditAnnotations(false); //暗号鍵の鍵長の指定 params.setEncryptionLengthInBits(256); foUserAgent.getRendererOptions().put("encryption-params", params); Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); String fo = "blog/encryptPDF.fo"; Result result = new SAXResult(fop.getDefaultHandler()); Source src = new StreamSource(new File(fo)); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); //PDF出力 transformer.transform(src, result); } catch (Exception e) { e.printStackTrace(); } finally { out.close(); } } }
図 2. encryptPDF.fo
<?xml version="1.0" encoding="UTF-8" ?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xml:lang="ja"> <fo:layout-master-set> <fo:simple-page-master page-width="210mm" page-height="297mm" margin-top="0mm" margin-left="0mm" margin-right="0mm" margin-bottom="0mm" master-name="PageMaster"> <fo:region-body margin-top="0mm" margin-left="0mm" margin-right="0mm" margin-bottom="0mm"/> <fo:region-before extent="0mm" /> <fo:region-after extent="0mm" /> <fo:region-start extent="0mm" /> <fo:region-end extent="0mm" /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="PageMaster"> <fo:flow flow-name="xsl-region-body"> <fo:block> <fo:instream-foreign-object content-width="210mm" content-height="297mm"> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="210mm" height="297mm" font-size="20" stroke-width="0.1mm"> <text x="4.9mm" y="10.5mm" fill="black">AES256bit暗号化PDF</text> </svg> </fo:instream-foreign-object> </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
図 3. 暗号化したPDF(クリックするとPDFを表示します。権限パスワードは、「owner」です。文書を開くパスワードは、「user」です。)
(このサンプルでは、encryptPDF.foの18行目に、font-family=”aoyagireisyo2″と追記して、OpenTypeフォントの「青柳隷書しも」を使用しております。)
2.最後に
このブログ記事が、実際のシステム開発に役立った方は、ぜひいいねボタンを押してください。またコメントもよろしくお願いいたします。(コメントするのに電子メールアドレス、名前、ウェブサイトは必須ではありません。入力なしで匿名でコメント可能です。)
©中條勝徳 and okulejp.com, 2012.
コメントを残す