12

大規模な Google 検索を行った結果、何らかの方法でデジタル署名の要点を見逃しているのではないかと考え始めています。

これは基本的に、私が原則としてできるはずだと信じていることであり、iTextSharp が私を許可してくれることを願っています。

私は C# と .NET で書いており、iTextSharp を使用して PDF ファイルを解析しています。署名されていない PDF ファイルと、同じファイルの署名済みバージョンがあります。

デジタル署名は基本的にPDFデータをハッシュし、秘密鍵で暗号化します。検証プロセスの一部は、公開鍵を使用してこれを復号化し、再度ハッシュしたときに結果がPDFデータと一致することを確認することです。

これに加えて、この復号化されたドキュメント ハッシュを取得し、署名されていない PDF から生成されたドキュメント ハッシュと比較したいと考えています。これは、署名された PDF が本物であることを確認するだけでなく、それが私が記録している署名されていない PDF と同じであることも確認したいためです。PDF データ (署名なし) と記録されている PDF データを比較することで、これを行うこともできると思います。

私は現在、これを行う方法を考え出していません!すなわち:

  1. 署名された PDF から署名を除いて PDF データを抽出するにはどうすればよいですか?
  2. または、署名されていない PDF からハッシュを生成するにはどうすればよいですか?
  3. 2. に加えて、PDF 署名から復号化されたハッシュを抽出するにはどうすればよいですか?

これが明確であることを願っています。私はどこかでポイントを逃していません!

4

2 に答える 2

7

これについて:

「これは、署名された PDF が本物であることを確認するだけでなく、記録にある署名されていない PDF と同じであることを確認したいからです」

サーバーで取得したドキュメントが本物であることを知りたいだけだとします。

署名済み文書を作成する場合、ファイルの一部のみに署名するか、文書全体に署名するかを選択できます。次に、「ドキュメント全体」の署名を使用できます。サーバーに返されたドキュメントが「本物」である場合 (つまり、署名の検証が成功したことを意味します)、記録されているドキュメントと同じであることは間違いありません。

PDF 署名には、承認署名と認証署名の 2 種類があることに注意してください。ドキュメントDigital Signatures in PDF from Adob​​e から:

(...) 承認署名。同意、承認、または受諾を示すために誰かが文書に署名します。認証済みドキュメントとは、ドキュメントの使用準備が整ったときに、作成者によって適用された認証署名を含むドキュメントです。発信者は、許可される変更を指定します。許可されている 3 つの変更レベルのいずれかを選択します。

  • 変更なし
  • フォーム記入のみ
  • フォームの記入とコメント

サーバー上にある特定の署名付き文書を、データベース上の署名されていない同等の文書と照合するとします。

文書の識別については、個別に処理することをお勧めします。ドキュメントを開くことができると、そのすべてのページの圧縮解除されたコンテンツの連結からハッシュ (たとえば md5) を作成し、それを元のドキュメントの別の同様のハッシュと比較できます (一度生成して保存することができます)。データベースで)。

私がこのようにする理由は、ドキュメントで使用された署名の種類から独立しているためです。PDF ファイルでフォーム フィールドが編集されたり、注釈が追加されたり、新しい署名が作成されたりしても、ページの内容は変更されず、常に同じままです。

iText を使用している場合は、メソッドPdfReader.getPageContentを使用してページ コンテンツのバイト配列を取得し、その結果を使用して MD5 ハッシュを計算できます

Java のコードは次のようになります。

PdfReader reader = new PdfReader("myfile.pdf");
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
int pageCount = reader.getNumberOfPages(); 
for(int i=1;i <= pageCount; i++)
{
     byte[] buf = reader.getPageContent(i);
     messageDigest.update(buf, 0, buf.length);
}
byte[] hash = messageDigest.digest();

さらに、署名なしで送信され、署名されて戻ってきたファイルをサーバーが受信した場合、署名はファイルのすべてではなく一部のみを参照している可能性があります。このシナリオでは、署名ダイジェストだけではファイルを特定できない可能性があります。

PDF仕様から(私のアカウントの太字のセクション):

署名は、ドキュメント内のデータ(またはデータの一部) のダイジェストを計算し、そのダイジェストをドキュメントに保存することによって作成されます。 PDF ファイルの一部:

- シグネチャ ディクショナリのByteRangeエントリで示される、ファイル内のバイト範囲に対してバイト範囲ダイジェストが計算されます。通常、この範囲はファイル全体であり、シグネチャ ディクショナリは含まれますが、シグネチャ値自体 (Contents エントリ) は含まれません。

- オブジェクト ダイジェスト (PDF 1.5) は、参照されたオブジェクト (通常はルート オブジェクト) からメモリ内のオブジェクトのサブツリーを選択的にウォークすることによって計算されます。結果のダイジェストは、それがどのように計算されたかに関する情報とともに、署名参照ディクショナリ (...) に配置されます。

于 2012-10-18T15:03:49.357 に答える
5

署名されたPDFの整合性を検証する戦略:

  1. そもそも署名されていないPDFを送信しないでください。iText(Linux対応アプリケーション用のJavaバージョン)を使用して、を使用してドキュメントに署名および認証CERTIFIED_FORM_FILLINGします。

  2. エンドユーザーに署名をフォームフィールドに追加して返送してもらいます。フォームを変更してもドキュメントの認証が破られることはないため、これを行うことができます。

  3. 署名とドキュメント認証の両方を検証します。

iTextのドキュメントからこれらすべてを行う方法を理解できるはずです:http: //itextpdf.sourceforge.net/howtosign.html

認定されたドキュメントがオリジナルと同じであることを確認するために必要なのは、ドキュメントのメタデータをオリジナルと比較することだけです。タイトルは潜在的に良い候補として頭に浮かぶ。

PDFからタイトルを取得してiTextを使用して比較するには、次のコードを使用します。

PdfReader reader = new PdfReader("AsignedPDF.pdf");
string s = reader.Info["Title"];
于 2012-10-16T15:20:56.507 に答える