PLOP DS と PDFlib を組み合わせて使用することで、
電子署名を付与した PDF を生成することができます。
既存 PDF に電子署名を付与する(PDF を生成する必要がない)場合は、必要な製品は PLOP DS のみです。
このサンプルで使用した電子署名は信頼された認証局で発行されたものではないため、Adobe Acorbat 等に開くと「少なくとも 1 つの署名に問題があります。」と表示されますが、信頼された認証局で発行された電子署名を使うと「署名済みであり、すべての署名が有効です。」と表示されます。
また、このサンプルは、 PLOP パッケージには含まれていない PDFlib 製品を必要としますが、PDFlib の無料評価版を当社 Web サイトから入手できます。
必要な製品:PDFlib PLOP DS / PDFlib
処理の流れ
①メモリ内に新規 PDF 文書を生成
begin_document() 関数で、メモリ内に新規 PDF 文書を生成します。
②フォントをロードする
load_font() 関数で使用したいフォントをロードします。
③PDF 文書ページを開く
① で作成した PDF 文書のページを open_page_ext() 関数を使用して開きます。
④位置決めをして文字列を出力する
ページを開いたあとは、例えば以下の関数を用いて PDF の内容を作りこんでいきます。
・load_font() … 文字列を表現するフォントを指定
・show() … 文字列の内容の設定
・moveto() と lineto() と stroke() … 直線を表示
・circle() と stroke() … 円を表示
PDFlib を使用したサンプルプログラムも別途ご用意しております。
⑤PDF ページを閉じる ⑥PDF 文書を閉じる
署名用の文字列の設定が完了したら、end_page_ext() 関数を用いてPDF 文書のページを閉じ、さらに end_document() 関数を用いて PDF 文書を閉じます。
ここまでで PDF の作成は完了し、次は作成した PDF に電子署名を付与します。
⑦メモリ内にある PDF 文書データを取得
get_buffer() 関数を使って、①~⑥で生成した PDF 文書のデータを変数に格納します。
この変数は、create_pvf() の引数で使用します。
⑧PVF(PDFlib Virtual File System) ファイルを生成する
create_pvf() 関数で PVF ファイルを生成します。
PVF とは、仮想の読み取り専用ファイルに名前を付けて、それを通常のファイル名と同じように扱えるというものです。
①~⑥で作成した PDF 文書はディスク上に実在しません。
電子署名を付与した状態でディスク上に PDF ファイルを出力すればよいので、この時点でディスク上に出力する必要はありません。
PVF ファイルを使用することで、処理速度の向上を見込むことができます。
仮想ファイル名は任意に名づけることができますが、ディスク上のファイルと名前衝突が発生しないようにしなければなりません。
⑨PVF ファイルから PDFlib で作った文書を開く
open_document() 関数を使って、⑧ で生成した PVF ファイルを開きます。
PVF ファイルは、通常のディスク上のファイルと同様にあらゆる API で扱うことができるため、
open_document() 関数で開くことができます。
⑩電子署名を作成する
prepare_signature() 関数で、オプションで指定したデジタル ID を用いて電子署名を作成します。
⑪電子署名を PDF に付与して出力する
create_document() 関数で、⑩ で作成した電子署名を ⑨ で開いた PVF ファイルに付与し、PDF としてディスク上に出力します。
⑫PDF 文書を閉じる
close_document() 関数で、⑪ で出力した PDF 文書を閉じます。
⑬PVF ファイルを削除する
delete_pvf() 関数で ⑧ で生成した PVF ファイルを削除します。
ソースコードと出力結果
/*
* 生成した PDF に電子署名を付与:
* PDFlib を用いてメモリ内に生成した動的な文書に対して、PLOP DS を使って電子署名を付与します。
* このサンプルには、PLOP DS の他、PDF の生成を行う PDFlib が必要です。
*
* 必要な製品 : PDFlib PLOP DS 5 及び PDFlib
* 必要なデータ : demo_signer_rsa_2048.p12
* demo_signer_rsa_2048.p12 は data ディレクトリにあります。
* demo_signer_rsa_2048.p12 のパスワードは demo です。
*/
import java.io.*;
import com.pdflib.PLOPException;
import com.pdflib.plop;
import com.pdflib.pdflib;
public class hellosign {
public static void main (String argv[]){
pdflib pdf = null;
plop plop = null;
try {
int font;
byte[] contents;
String optlist;
int doc;
/* 本サンプルに必要なデータが保存されているディレクトリを指定する */
String searchpath = "../data";
final String out_filename = "hellosign.pdf";
/* 基本的な署名オプション */
String sign_opts =
/* ltv オプション:長期検証(LTV)をするかどうかを指定する。
LTV を行う場合は full を指定する(デフォルト:try) */
"ltv=try " +
/* engine オプション:電子署名を作成するための暗号化エンジンを指定(デフォルト:builtin)
digitalid オプション:使用するデジタル ID を指定する
password オプション:デジタル ID に対するパスワード等を指定する */
"engine=builtin digitalid={filename=demo_signer_rsa_2048.p12} password={demo} ";
/* ----------- ステップ1: PDFlib を用いてメモリ内に動的に文書を生成します ---------- */
/* PDFlib オブジェクトを作成する */
pdf = new pdflib();
/* ①メモリ内に新規PDF文書を生成 */
pdf.begin_document("", "");
/* 文書の作成者やタイトル等、文書情報フィールドを設定する */
pdf.set_info("Creator", "hellosign.java");
pdf.set_info("Author", "Rainer Ploeckl");
pdf.set_info("Title", "Hello world/signed (Java)");
/* ②フォントをロードする */
font = pdf.load_font("Helvetica-Bold", "winansi", "");
/* ③PDF 文書ページを開く */
pdf.begin_page_ext(595, 842, "");
/* ④位置決めをして文字列を出力する */
pdf.setfont(font, 24);
pdf.set_text_pos(50, 700);
pdf.show("Hello world/signed!");
pdf.continue_text("(says Java)");
/* ⑤PDF ページを閉じる ⑥PDF 文書を閉じる */
pdf.end_page_ext("");
pdf.end_document("");
/* ⑦メモリ内にある PDF 文書データを取得 */
contents = pdf.get_buffer();
/* ----------- ステップ2 : PLOP DS を用いて文書に署名します ---------- */
/* PLOP オブジェクトを作成する */
plop = new plop();
/* 読み込みたいファイルの入ったディレクトリを指定する */
optlist = "searchpath {" + searchpath + "} ";
plop.set_option(optlist);
/* ⑧PVF(PDFlib Virtual File System)ファイルを生成する */
plop.create_pvf("/pvf/hello.pdf", contents, "");
/* ⑨PVF ファイルから PDFlib で作った文書を開く */
if ((doc = plop.open_document("/pvf/hello.pdf", "")) == -1) {
throw new Exception("Error: " + plop.get_errmsg());
}
/* ⑩電子署名を作成する */
if (plop.prepare_signature(sign_opts) == -1) {
throw new Exception("Error: " + plop.get_apiname() + ": " + plop.get_errmsg());
}
/* ⑪電子署名を PDF に付与して出力する */
if (plop.create_document("hellosign.pdf", "input=" + doc) == -1) {
throw new Exception("Error: " + plop.get_apiname() + ": " + plop.get_errmsg());
}
/* ⑫PDF文書を閉じる */
plop.close_document(doc, "");
/* ⑬PVFファイルを削除する */
if (plop.delete_pvf("/pvf/hello.pdf") == -1) {
throw new Exception("Error: " + plop.get_errmsg());
}
} catch (PLOPException e) {
System.err.println("PLOP exception occurred in hellosign sample:");
System.err.println("[" + e.get_errnum() + "] " + e.get_apiname() + ": " + e.get_errmsg());
} catch (Exception e) {
System.err.println(e);
} finally {
/* PLOP オブジェクトを削除する */
if (plop != null) plop.delete();
/* PDFlib オブジェクトを削除する */
if (pdf != null) {
try {
pdf.delete();
} catch (Exception e) {
System.exit(2);
}
}
}
}
}