前提・実現したいこと
PHPのTCPDFにおいて、PDFにタイムスタンプを付与する
発生している問題・エラーメッセージ
setTimeStampというファンクションがありますが、タイムスタンプが付与されません。 通常の署名付きPDFが出力されます。
該当のソースコード
PHP
1//set tsa server url 2$tsa_host = 'https://freetsa.org/tsr'; 3//specify PEM file(Optional) 4$tsa_username = ''; 5//specify cert file password(Optional) 6$tsa_password = ''; 7//specify the path of crt file(Optional) 8$tsa_cert = ''; 9//setTimeStamp 10$tcpdf->setTimeStamp($tsa_host, $tsa_username, $tsa_password, $tsa_cert);
試したこと
setTimeStampによるタイムスタンプ付与を実現したいというのもあるのですが、
PDFのタイムスタンプとTCPDFのファンクションについて頭がごちゃごちゃになっているので、ひとまずこちらを整理できればと思います。
このファンクションを根本から理解するため、setTimeStampファンクションのほか、TSAやOpenssl・curlを使用したタイムスタンプリクエスト送信、PDFの内部構造などについて色々と調べてみましたが、
国内外問わずリファレンスがかなり少なく、推測の域をなかなか抜け出せないままスタックしてかなりの時間が経過しているので質問させていただきました。
ひとまず、PDFへのタイムスタンプ付与の仕組みについてはPDFへの署名時に使うCertificateファイルの証明書情報の中に、
タイムスタンプサーバーから返ってきたタイムスタンプレスポンスの中から取り出したタイムスタンプを、PKCS#7形式でPDFの指定の場所に埋め込むことで「タイムスタンプ埋め込み式署名」として機能する、ということは理解しています。
そしてここからなのですが、上記のように署名を行うには、まずタイムスタンプサーバーにリクエストを送る必要があり、その為の上記ソースコードなのだと思います。
しかしながら、TCPDFには署名自体を行うためのsetSignatureファンクションがあります。
php
1setSignature( $signing_cert = '', $private_key = '', $private_key_password = '', $extracerts = '', $cert_type = 2, $info = array(), $approval = '')
このファンクションでは、
- $signing_certで証明書ファイルを指定
- $private_keyで秘密鍵ファイルを指定
- $private_key_passwordで秘密鍵ファイルのパスワードを指定
・・・などを行って、PDFに署名を施すことが可能ですが、前述の
タイムスタンプサーバーから返ってきたタイムスタンプレスポンスの中から取り出したタイムスタンプを、PKCS#7形式でPDFの指定の場所に埋め込むことで「タイムスタンプ埋め込み式署名」として機能する
ということを考えると、setSignatureファンクションをsetTimeStampファンクションと組み合わせてコーディングする必要があると考えています。
実際、setTimeStampファンクションのリファレンスをみてみると、概要に「Use with digital signature only!」との表記があります。
そのため、当初は単に「通常通りsetSignatureとsetTimeStampをコーデイングすればいいか」と考え、コーディングしましたが、setTimeStampが機能しません。
PHPの「上から順に処理される」という前提もありますので、記述順を変えてみたりなどしましたがなかなかタイムスタンプが付与されません。
あとは、単純にsetTimeStampのパラメータ設定が間違っているのかと思い、使用しているFreeTSA指定の証明書ファイル及びリクエストファイル指定を何度も見直してみましたが、こちらもダメでした。
また、独自でcurlのPOSTを用いてタイムスタンプ処理をTCPDFの処理に割り込ませることも考えましたが、こちらも撃沈しました。
そもそもPDFへはAdobe Readerにて増分更新でタイムスタンプを付与すればいい話なのですが、出来うる処理は全てサーバーライブラリにて処理を行いたく、開発を行なっております。
そのためTCPDFを利用することになるのですが、TCPDFは増分更新には対応していないという仕様があり、追加で別のタイムスタンプ署名を付与することはできないので、自ずとsetSignatureで指定した証明書及び秘密鍵ファイルを使用して生成される署名の中に含まれたタイムスタンプを利用することになると思います。
ただ、そうするとそもそもsetTimeStampでタイムスタンプサーバーを指定してもタイムスタンプが付与されないのでは?とも思っています。
加えて、タイムスタンプサーバーへリクエストをPOSTする際、対象データが必要となりますが、TCPDFのsetTimeStampファンクションには対象データを指定するパラメータがありません。
これはTCPDF内部で生成するPDFを対象データに指定されるようにしているのでしょうか。
また、こちらは別の疑問ですが、Certificate Transparencyに対応した証明書ファイルにはSCTが含まれておりますが、これはタイムスタンプサーバーのレスポンスから取り出すタイムスタンプとは異なるのでしょうか。
今月末までになんとか突破口を見つけたいのですが、どうしても根本からこれらの疑問を解消したいため、お時間の頂戴できる方にお伺いできれば幸いです。
よろしくお願いいたします。
参考サイト
下記のサイト様を参考にさせていただきました。
TCPDF::setTimeStamp()
FreeTSA.org
PDF/A に電子署名してみる
Let's EncryptのCertificate Transparency対応
Certificate Transparencyについて勉強会で発表したので、その補足や落ち穂拾い
あなたの回答
tips
プレビュー