PDFへのデジタル署名
-
05-07-2019 - |
質問
私の会社にはWebドキュメント管理アプリケーションがあり、ユーザーのデジタル証明書を使用してpdfファイルに署名する方法を見つけるように割り当てられています。
pdfは数キロバイトから100メガバイトを超える場合があります。これはインターネット上で行われるため、Webサーバーで署名が必要です 。
これを行うために、ユーザーに証明書の選択を求めるactiveXコントロールを作成し、WebClient.UploadDataを使用して証明書をバイト配列として送信してWebページにアップロードします。
PDFドキュメントに署名しようとすると、Webページで「キーが存在しません」というエラーが表示されます。適切な証明書を選択した後、https接続を介して直接証明書を使用していた場合、キーのプロンプトが表示されるため、これは驚くことではありません。これはactiveXでは発生しません。
これは、ユーザーから証明書を取得する方法です:
private static X509Certificate2 PickCertificate()
{
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);
// pick a certificate from the store
X509Certificate2 cert = X509Certificate2UI.SelectFromCollection(store.Certificates, "Title", "Message", X509SelectionFlag.SingleSelection)[0];
// show certificate details dialog
X509Certificate2UI.DisplayCertificate(cert);
store.Close();
return cert;
}
finally { store.Close(); }
}
不足しているキーを提供するようにユーザーに依頼するにはどうすればよいですか?
解決
ユーザーが証明書に秘密鍵をアップロードして、PDFに署名できるようにする必要がありますか?もしそうなら、それはセキュリティの観点から根本的に壊れています。
公開証明書!=秘密鍵という点を見逃していると思います。 (私たちのほとんどはずさんで、「証明書」という言葉を使用してそれらのいずれか(または両方)を指しているため、完全に驚くことではありません)。メモリから取得すると、CryptoAPIには、キーにアクセスできるメソッドの選択セットのみがあります。 「PFXとしてエクスポート」が必要です。これらの方法の中で、本当に、本当にしたいのであれば、あなたのデザインを動作させることができますが、これをお勧めする方法はありません。 (秘密鍵をWebサーバーに送信するリスク、拒否された否認防止など)。
サーバー上で本当に署名する必要がある場合[引数をあまり理解していないため、署名によってアップロードに多くのデータが追加されることはありません]、おそらく多層アーキテクチャとキーエスクローメカニズムを検討する必要があります。これにより、少なくともセキュリティ上の懸念を最小限に抑えることができます(ただし、否認防止性は失われます...そして、他のリスクが発生します。無料のランチはありません)。
そのため、PDFファイルがアップロードされる前に、(ActiveXコントロール内の)クライアントでPDF署名が発生するように、おそらくアプリケーションの再設計を検討する必要があります。 このSOスレッドで説明されているように、署名ステップにサードパーティのライブラリが必要になると思います。