لذا لقد حان المهمة. باستخدام متصفح ، قم بدعوة المستخدم لتوقيع ملف PDF بتوقيع إلكتروني (يشار إليه فيما يلي باسم EP). يجب أن يكون لدى المستخدم رمز مميز يحتوي على الشهادة والمفاتيح العامة والخاصة. بعد ذلك على الخادم ، تحتاج إلى إدراج التوقيع في مستند PDF. بعد ذلك ، تحتاج إلى التحقق من صحة التوقيع. نستخدم ASP.NET ، وبالتالي ، C # كالخلفية.
كل الملح هو أنك تحتاج إلى استخدام توقيع بتنسيق CAdES-X Long Type 1 ، والروسية GOST R 34.10-2001 ، GOST R 34.10-2012 ، إلخ. بالإضافة إلى ذلك ، يمكن أن يكون هناك أكثر من توقيع واحد ، أي أنه يمكن للمستخدمين بالتناوب في التوقيع على ملف. ومع ذلك ، يجب أن تظل التوقيعات السابقة صالحة.
في عملية حل المشكلة ، قرروا تعقيدنا وتقليل كمية البيانات المرسلة إلى العميل. إرسال تجزئة المستند فقط ، ولكن ليس المستند نفسه.
في شفرة المصدر ، سأحذف اللحظات ذات الأهمية الضئيلة للموضوع ، سأترك ذلك فقط مثل التشفير. سأعطي كود JS فقط للمتصفحات العادية التي تدعم محركات JS الخاصة بها Promise and function generator. أعتقد من يحتاج إلى الكتابة لـ IE بأنفسهم (كان علي أن "لا أريد أن").
ما تحتاجه:
- يجب أن يتلقى المستخدم زوج مفاتيح وشهادة.
- يجب على المستخدم تثبيت المكون الإضافي من Crypto PRO. بدون هذا ، لن نتمكن من العمل مع مزود خدمة التشفير باستخدام أدوات JS.
ملاحظات:
- بالنسبة للاختبارات ، حصلت على شهادة صادرة عن اختبار Crypto PRO CA ورمز عادي استلمه أحد موظفينا (في وقت كتابة هذا التقرير ~ 1500r مع ترخيص سنوي لـ Crypto PRO وشهادتين: لكن "الجديدة" و "القديمة" 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 ، يتم تمرير وظيفة المولد إليها ، حيث يتم استدعاء () التالي على التوالي ، مما يؤدي إلى الانتقال إلى العائد.
وبالتالي ، نحصل على تناظرية معينة من انتظار غير متزامن من C #. كل شيء يبدو متزامنًا ، ولكنه يعمل بشكل غير متزامن.
الآن ما يحدث على الخادم عند طلب التجزئة.
أولاً ، تحتاج إلى تثبيت حزمة iTextSharp nuget (في وقت الكتابة ، يجب أن يكون الإصدار الحالي 5.5.13)
ثانيًا ، هناك حاجة إلى CryptoPro.Sharpei ، فهو يذهب إلى تحميل Crypto PRO .NET SDK
الآن يمكنك الحصول على التجزئة
على العميل ، بعد وجود تجزئة من الخادم ، وقعنا عليه
تعليق: إرسال التوقيع المستلم إلى الخادم (انظر أعلاه)
حسنًا ، أخيرًا ، أدخل التوقيع في المستند على جانب الخادم
تعليق: SimpleExternalSignatureContainer هي أبسط فئة تطبق واجهة IExternalSignatureContainer.
في الواقع مع توقيع ملف PDF ، هذا كل شيء. سيتم وصف التحقق في استمرار المقال. آمل أن تكون ...
إجراء تصحيحات من التعليق عند استلام خوارزمية توقيع Oid. شكرا لك