トラスト・ソフトウェア・システム
トラスト・ソフトウェア・システム

PDF Security(複数の電子署名) C++サンプル

PDF Security テクニカル・チャート
「PDF Security」ソフトは、PDF文書への電子署名と暗号化の機能をアプリケーションに追加します。

電子署名 ・ タイムスタンプ
PDF Securityは、電子署名の様々なタイプを適用します。PDF Securityは、PDF/Aに準拠した電子証明書失効情報(CRLやOCSPのデータ)の埋め込みや、RFC3161タイムスタンプを追加します。
PDF Securityは、証明書のルート(CA、中間)証明書や失効情報をチェックすることで電子署名の有効性を検証します。また、タイムスタンプによる検証も行います。
電子署名しないでタイムスタンプだけを埋め込めます。

暗号化・セキュリティ フラグ
PDF文書は、それが重要な場面で利用される場合、データの不正なアクセスや改竄から保護するために、暗号化やセキュリティ(アクセス許可)フラグなどを設定します。

機能概要はこちらです。
C#VB6.0 および Java のサンプルを公開しています。
無償評価版(リンク先は英語)はこちらです。 ダウンロード手順
価格見積り

無償評価版のダウンロードとインストール

 ライブラリ(評価版API)は無償でダウンロード(試用)できますので、PDF Security ダウンロード手順を参照してダウンロードください。
 ファイルをダウンロードしてから、インストールもしくは適当なフォルダーに解凍します。以下のようなフォルダーができあがりますので、適宜ご利用ください。
binライブラリやライセンスマネージャーなど
doc使用説明書やjavadocなど
includeC/C++用のヘッダー(.h)ファイル
jarSECA.jar(Javaのラッパー)
libC/C++用のlibファイル
samples各種開発言語のサンプル
サンプルの実行前に、bin/PdfSecureAPI.dllをサンプル実行イメージと同じフォルダーにコピーしてください。また、無償評価版と共にダウンロードしたライセンスキーをbin/LicenseManager.exeを使って登録してください。 ライセンスキーの登録方法はこちらです。

PDFに複数の署名を適用する

PDF/A 複数電子署名
PDF/A規格に準拠していて、変更できません。
この文書には、二つの署名が適用されています。
署名前のPDF/A文書署名後のPDF/A文書
 PDF Tools 「PDF Security」電子署名ライブラリ(API)を使って、左のようにPDF/A文書に複数の電子署名を適用します。

ライブラリ(評価版API)は無償でダウンロード(試用)できます、PDF Security ダウンロード手順を参照してください。 単一の署名を適用するには、PDF Security 解説とサンプルを参照してください。 Acrobat Readerでの署名検証方法は、こちらです。

複数署名の手順

 複数の電子署名をPDF文書に適用するには、電子署名の都度PDF文書を作成(書き出し)しなければなりません。そのためPDF Securityには、結果をメモリ上に(ファイルではなく)PDF文書を出力する機能を備えています。 この機能によって、複数の電子署名をより簡単に追加できます。
複数の署名は以下の手順に従って適用します。
1.PDF文書をハンドルするインスタンスを生成し、電子署名を施すPDF文書をファイルから読み込む。
2.電子署名のインスタンスを生成し、署名の詳細を指定する。
3.ファイルから読み込んだPDFのインスタンスに準備した電子署名のインスタンスで電子署名を追加する。
4.PDFのインスタンスをメモリに出力する。
5.ファイルから作成したPDFのインスタンスとは別のPDFインスタンスを生成し、そこにメモリ上のPDFを読み込む。
6.2番目の電子署名のインスタンスを生成し、署名の詳細を指定する。
7.メモリ上のPDFのインスタンスに、2番目の電子署名インスタンスで電子署名を追加する。
8.3つ以上の電子署名を追加する場合は、手順4と同様に電子署名を追加したPDFのインスタンスをメモリ上に出力し、それを読み込んで電子署名の追加を繰り返す。
9.最後の署名が追加されたPDFのインスタンスを、名前を指定してファイルに出力する。
10.不要になったインスタンスを開放する。

手順1. PDFインスタンス生成

 PDF文書のインスタンスを生成して、そこにファイルからPDF文書を読み込みます。
#include <stdio.h>
#include "pdfsecureapi_c.h"
#include "pdfsecuritydecl.h"

int main()
{
    TPDFErrorCode   err;

    PdfSecureInitialize();

    // 文書インスタンスを生成する
    TPdfSecure*	    pDocument;
    pDocument = PdfSecureCreateObject();
    PdfSecureSetNoCache(pDocument, 1);

    // PDF文書を読み込む
    if(!PdfSecureOpen(pDocument, "Receipt2a.pdf", "")){
        printf("Error opening PDF file %s.\n", "Receipt2a.pdf");
        printf("Error 0x%X\n", PdfSecureGetErrorCode(pDocument));
        return 1;
    }
PdfSecureInitialize( )PDFSecurity APIを初期化します。
PdfSecureNoCache( )第二引数に応じてCRLなどをキャッシュしないようにします。 [省略可]
PdfSecureCreateObject( )PDFのインスタンスを生成します。
PdfSecureOpen( )ファイル名を指定して、生成したインスタンスにPDF文書を読み込みます。
 (インターネット上のPDFファイルを読み込む場合
第三引数には、PDFを暗号化した際のオーナーまたは、ユーザーパスワードを指定します。

手順2. 電子署名インスタンス生成と詳細指定

 電子署名のインスタンスを生成し、電子証明書や印影その表示位置などを指定します。
//電子署名
TPdfSignature* pSignature;
TPDFRect       rect;
int            x,y, w,h;

//インスタンス生成
pSignature = PdfSignatureCreateObject();

//指定フォント
PdfSignatureSetFontName1(pSignature, "C:\\Windows\\Fonts\\msgothic.ttc");
PdfSignatureSetFontName2(pSignature, "C:\\Windows\\Fonts\\msmincho.ttc");

//電子証明書情報(電子証明書検索情報)
PdfSignatureSetName(pSignature, "山田 太郎");

//表示位置
float x1=470,y1=600, x2=500,y2=630;
rect.m_fRect[0]=x1, rect.m_fRect[1]=y1;
rect.m_fRect[2]=x2, rect.m_fRect[3]=y2;
PdfSignatureSetRect(pSignature, &rect);

//電子署名の背景画像
PdfSignatureSetImageFileName(pSignature, "Hanko.png");

//ページ
PdfSignatureSetPageNo(pSignature, -1);

//タイムスタンプ(RFC3161)
PdfSignatureSetTimeStampURL(pSignature, "http://ca21.trustss.jp/tsa/");
PdfSignatureSetName( ) 電子署名する電子証明書のCN(Common Name、所有者名)を指定します。
さらに詳しく証明書を指定する場合や、署名領域の内容を指定する場合は以下のコードを追加します。
PdfSignatureSetIssuer(pSignature, "CA21-5");
PdfSignatureSetSerialNumber(pSignature, "15 A3");
PdfSignatureSetReason(pSignature, "受領済");
PdfSignatureSetLocation(pSignature, "東京");
PdfSignatureSetIssuer( )電子署名する電子証明書の発行者を指定します。
電子証明書の所有者名だけで証明書が特定できる場合は、この指定は省略できます。しかし、電子証明書をシリアル番号で指定する場合は、所有者の指定が必須です。
PdfSignatureSetSerialNumber( )電子署名する電子証明書をシリアル番号で指定します。
PdfSignatureSetReason( )電子署名の理由を指定します。 [省略可]
PdfSignatureSetLocation( )電子署名の場所を指定します。 [省略可]
PdfSignatureSetRect( ) 電子署名の領域を左下(x1,Y1)と右上(x2,y2)で指定します。単位はポイント(1ポイント=1/72インチ)です。 [省略可]
A4サイズの場合は、左下(0,0)、右上(595,842)となります。
署名領域に画像を貼り付けずに枠線や背景色を指定する場合は、以下のコードを追加します。
PdfSignatureSetStrokeColor(pSignature, 10053120);
PdfSignatureSetFillColor(pSignature, 6724095);
PdfSignatureSetStrokeColor( )電子署名領域に画像を指定しなかった場合に表示される境界線の色を指定します。 [省略可]
PdfSignatureSetFillColor( )電子署名領域に画像を指定しなかった場合に、その領域が塗りつぶされる色を指定します。 [省略可]
PdfSignatureSetImageFileName( )電子署名の領域に貼り付ける画像を指定します。 [省略可]
PdfSignatureSetPageNo( )電子署名領域を表示するページを指定します。 [省略可]
-1を指定すると、最終のページに表示されます。また、省略した場合や存在しないページを指定した場合も、最終のページに表示されます。
PdfSignatureSetTimeStampURL( )指定のタイムスタンプを電子署名と共に埋め込みます。 [省略可]

署名領域に文字列を表示させたくない場合は、以下のコードを追加します。
PdfSignatureSetText1(pSignature, "\t0,0 ");
PdfSignatureSetText2(pSignature, "\t0,0 ");
PdfSignatureSetText1( )電子署名領域に表示される署名者の情報を指定する文字列にします。 [省略可]
表示位置と表示する文字列を以下の形式に従って指定します。
<TAB>X位置,Y位置<空白>文字列
PdfSignatureSetText2( )電子署名領域に表示される署名者以外の情報を指定する文字列にします。 [省略可]
表示位置と表示する文字列を以下の形式に従って指定します。
<TAB>X位置,Y位置<空白>文字列
注意)指定したタイムスタンプのURLは、テスト用のタイムスタンプを発行するTSAです。このTSAは無償・無登録で自由に使えますが、負荷によってはレスポンスが低下します。

手順3. PDF文書に電子署名を追加

 PDF文書のインスタンスに電子署名を追加します。
//電子署名追加
if(!PdfSecureAddSignature(pDocument, pSignature)){
    printf("Error setting signature.\n");
    printf("Error 0x%X\n", PdfSecureGetErrorCode(pDocument));
    return 2;
}
PdfSecureAddSignature( )引数に指定した電子署名をPDF文書に追加します。

手順4. PDFデータをメモリに出力

 電子署名されたPDFデータをメモリ上に出力します。不要になったPDFファイルを閉じます。
if(!PdfSecureSaveInMemory(pDocument,"","",ePermNoEncryption,128,NULL,NULL)){
    printf("Error creating to memory\n");
    printf("Error 0x%X\n", PdfSecureGetErrorCode(pDocument));
    return 3;
}
PdfSecureClose(pDocument);
PdfSecureSaveInMemory( )PDFデータをメモリ上に出力します。以下のとおり引数を指定します。
第二引数ユーザーパスワードを指定します。
""(NULL)を指定すると、既定のパスワードが使われます。
第三引数オーナーパスワードを指定します。
""(NULL)を指定すると、ユーザーパスワードが使われます。
第四引数パーミッション・フラグを指定します。
PDF/A文書に電子署名する場合は、ePermNoEncryptionを指定します。
第五引数暗号化の鍵長を指定します。
第六引数暗号化フィルターを指定します。
第七引数ストリーム暗号化フィルターを指定します。
PdfSecureClose( )読み込み用に開いたPDFファイルを閉じます。

手順5. 新たなPDF文書インスタンスを生成

 新たなPDF文書のインスタンスを生成し、メモリ上のPDFデータを読み込みます。
TPdfSecure* pDocument2 = PdfSecureCreateObject();
PdfSecureSetNoCache(pDocument2, 1);
TPDFByteArray *ps = PdfSecureGetPdf(pDocument);
if(!PdfSecureOpenMem(pDocument2, ps->m_pData, ps->m_nLength ,"")){
    printf("Error opening PDF file in Memory.\n");
    printf("Error 0x%X\n", PdfSecureGetErrorCode(pDocument2));
    return 4;
}
PdfSecureCreateObject( )新たなPDFのインスタンスを生成します。
PdfSecureNoCache( )第二引数に応じてCRLなどをキャッシュしないようにします。 [省略可]
PdfSecureGetPdf( )メモリに格納されたPDF文書をバイトストリームとして読み込めるようにします。
PdfSecureOpenMem( )メモリ中のPDF文書を読み込みます。
第二、第三引数PdfSecureGetPdf( )で受け取ったバイトストリームを指定します。
第四引数PDFを暗号化した際のオーナーまたは、ユーザーパスワードを指定します。

手順6. 次の電子署名インスタンスを生成

 さらに追加する電子署名のインスタンスを生成し、署名の詳細を設定します。 設定は、手順2と同様です。
TPDFRect  rect2;

//インスタンス生成
TPdfSignature* pSignature2 = PdfSignatureCreateObject();

//指定フォント
PdfSignatureSetFontName1(pSignature2, "C:\\Windows\\Fonts\\msgothic.ttc");
PdfSignatureSetFontName2(pSignature2, "C:\\Windows\\Fonts\\msmincho.ttc");

//電子証明書情報(電子証明書検索情報)
PdfSignatureSetName(pSignature2, "山田 次郎");
PdfSignatureSetIssuer(pSignature2, "CA21-5");
PdfSignatureSetSerialNumber(pSignature2, "15 A4");

//電子署名表示内容
PdfSignatureSetReason(pSignature2, "確認済");
PdfSignatureSetLocation(pSignature2, "東京");

//電子署名部分の色、位置
PdfSignatureSetStrokeColor(pSignature2, 10053120);
PdfSignatureSetFillColor(pSignature2, 6724095);
float x1=470,y1=565, x2=500,y2=595;
rect2.m_fRect[0]=x1, rect2.m_fRect[1]=y1;
rect2.m_fRect[2]=x2, rect2.m_fRect[3]=y2;
PdfSignatureSetRect(pSignature2, &rect2);

//電子署名の背景画像 他
PdfSignatureSetImageFileNameA(pSignature2, "Hanko.png");
PdfSignatureSetText1(pSignature2, "\t0,0 ");
PdfSignatureSetText2(pSignature2, "\t0,0 ");

//タイムスタンプ(RFC3161)
PdfSignatureSetTimeStampURL(pSignature2,"http://ca21.trustss.jp/tsa/");

手順7. 次の電子署名を追加する

 次の電子署名を追加します。 手順3と同様です。
if(!PdfSecureAddSignature(pDocument2, pSignature2)){
    printf("Error setting signature.\n");
    printf("Error 0x%X\n", PdfSecureGetErrorCode(pDocument2));
    return 5;
}

手順8. さらに電子署名を追加する場合

 さらに電子署名を追加するには、手順4と同様にして結果をメモリに出力します。出力したPDFをさらに手順5と同様に別のPDFインスタンスに格納します。 そして、電子署名のインスタンスを準備し(手順6)、PDFに署名を追加(手順7)を繰り返します。

手順9. 結果をファイルに出力

 電子署名が追加されたPDFをファイルに出力します。
if(!PdfSecureSaveAs(pDocument2,"Receipt3.pdf","","",ePermNoEncryption,128,"","")){
    printf("Error creating output file %s.\n","Receipt00.pdf");
    printf("Error 0x%X\n", PdfSecureGetErrorCode(pDocument2));
    return 6;
}
第二引数に出力するファイル名を指定します。
第三引数以降は手順4と同様です。

手順10. 不要になったインスタンスを開放

 以下のように実行します。
PdfSecureClose(pDocument2);
PdfSignatureDestroyObject(pSignature);
PdfSignatureDestroyObject(pSignature2);
PdfSecureDestroyObject(pDocument);
PdfSecureDestroyObject(pDocument2);
PdfSecureUnInitialize();

サンプル

 複数の電子署名を追加するC++のサンプルは、こちらです。 このサンプルを実行するには電子証明書が必要です。

ご質問、お問い合わせ

 メールで support@TrustSS.co.jp 宛てにお送りください。
または、質問のページからお送りいただくようお願いします。ご要望も承っております。(匿名で送れます。)

(記載の会社名および製品名は、各社の登録商標および商標です。)
PDF製品 C++サンプル
PDF Security
PDF Validator
PDF to PDF/A Converter
PDF to Image Converter
PDF Imager-LP
Image to PDF Converter
PDF Printer
PDF Prep Tool Suite
PDF Optimizer
PDF Command Line Suite
PDF Extract