だから。 タスクが来ました。 ブラウザーを使用して、ユーザーを電子署名(以降EPと呼びます)でPDFに署名するように招待します。 ユーザーは、証明書、公開鍵および秘密鍵を含むトークンを持っている必要があります。 次に、サーバー上で、PDFドキュメントに署名を挿入する必要があります。 その後、署名の有効性を確認する必要があります。 ASP.NETと、それに応じてバックエンドとしてC#を使用します。
すべてのソルトは、CAdES-Xロングタイプ1形式の署名と、ロシアのGOST R 34.10-2001、GOST R 34.10-2012などを使用する必要があるということです。 さらに、複数の署名が存在する可能性があります。つまり、ユーザーはファイルに交互に署名することができます。 ただし、以前の署名は有効なままでなければなりません。
問題を解決する過程で、彼らは私たちを複雑にし、クライアントに送信されるデータの量を減らすことにしました。 ドキュメントのハッシュのみを送信し、ドキュメント自体は送信しません。
ソースコードでは、このトピックにとってほとんど意味のない瞬間を省略します。暗号に関することだけを残します。 JSコードは、JSエンジンがPromiseおよびFunction Generatorをサポートする通常のブラウザーにのみ提供します。 誰がIEのために自分で書く必要があると思います(「やりたくない」必要がありました)。
必要なもの:
- ユーザーはキーペアと証明書を受け取る必要があります。
- ユーザーは、Crypto PROからプラグインをインストールする必要があります。 これがないと、JSツールを使用して暗号化プロバイダーと連携できなくなります。
備考:
- テストについては、テストCrypto PRO CAによって発行された証明書と、従業員の1人が受け取った通常のトークンがありました(執筆時点で、Crypto PROの年間ライセンスと2つの証明書を持つ〜1500r、ただし「新しい」および「古い」GOST)
- 彼らはプラグインがViPNetで動作することができると言っていますが、私はそれをテストしていません。
ここで、サーバーに署名可能なPDFがあると仮定します。
Crypto PROからページにスクリプトを追加します。
<script src="/Scripts/cadesplugin_api.js" type="text/javascript"></script>
次に、cadespluginオブジェクトが形成されるまで待つ必要があります
window.cadespluginLoaded = false; cadesplugin.then(function () { window.cadespluginLoaded = true; });
ハッシュサーバーに問い合わせます。 以前は、このために、ユーザーが署名する証明書、したがってアルゴリズムを知る必要があります。 ちょっとしたコメント:クライアント側で暗号化を操作するためのすべての関数と「変数」をCryptographyObjectに統合しました。
CryptographyObjectオブジェクトの証明書フィールドに入力する方法:
fillCertificates: function (failCallback) { cadesplugin.async_spawn(function*() { try { let oStore = yield cadesplugin.CreateObjectAsync("CAPICOM.Store"); oStore.Open(cadesplugin.CAPICOM_CURRENT_USER_STORE, cadesplugin.CAPICOM_MY_STORE, cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED); let certs = yield oStore.Certificates; certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID); let certsCount = yield certs.Count; for (let i = 1; i <= certsCount; i++) { let cert = yield certs.Item(i); CryptographyObject.certificates.push(cert); } oStore.Close(); } catch (exc) { failCallback(exc); } }); }
コメント:証明書ストアを開こうとしています。 この時点で、ユーザーのシステムは、サイトが証明書、暗号化、およびその他の魔法の、理解できないナンセンスで何かをしようとしていることを警告します。 ユーザーは「はい」ボタンをクリックする必要があります
次に、期限内に有効な証明書を取得し、証明書配列に追加します。 これは、cadespluginの非同期性のために行う必要があります(IEでは、すべてが異なります;))。
ハッシュ方法:
getHash: function (certIndex, successCallback, failCallback, - ) { try { cadesplugin.async_spawn(function*() { let cert = CryptographyObject.certificates[certIndex]; let certPublicKey = yield cert.PublicKey(); let certAlgorithm = yield certPublicKey.Algorithm; let algorithmValue = yield certAlgorithm.Value; let hashAlgorithm;
コメント:cadesplugin.async_spawnに注意してください。ジェネレーター関数がcadesplugin.async_spawnに渡され、その上でnext()が順次呼び出され、yieldへの移行につながります。
したがって、async-awaitの特定のアナログをC#から取得します。 すべてが同期的に見えますが、非同期で動作します。
ハッシュが要求されたときにサーバー上で何が起こるか。
最初に、iTextSharp nugetパッケージをインストールする必要があります(執筆時点では、現在のバージョン5.5.13が必要です)
第二に、CryptoPro.Sharpeiが必要です。CryptoPRO .NET SDKの負荷になります
これでハッシュを取得できます
クライアントで、サーバーからのハッシュを取得して、署名します
コメント:受信した署名をサーバーに送信します(上記を参照)
最後に、サーバー側のドキュメントに署名を挿入します
コメント:SimpleExternalSignatureContainerは、IExternalSignatureContainerインターフェイスを実装する最も単純なクラスです。
実際にPDFの署名があれば、それだけです。 検証については、記事の続きで説明します。 彼女が...
Oid署名アルゴリズムの受信に関するコメントを修正しました。 ありがとう