المقدمة والدافع

عند تنفيذ التوقيعات الرقمية في أنظمة على مستوى المؤسسات،
الأمان أمر لا يمكن التفاوض عليه.
تخزين شهادة في ملف PFX أو P12 محلي مريح لكنه يعرض المفتاح الخاص للاستخراج أو الاختراق. وعلى النقيض من ذلك،
الرموز المادية PKCS#11 (مثل مفاتيح USB، البطاقات الذكية، وأجهزة HSM)
تحافظ على المفاتيح داخل حدود مقاومة للعبث، مما يضمن عدم خروجها من الجهاز أبدًا.

توضح هذه المقالة كيفية استخدام GroupDocs.Signature for .NET
مع Pkcs11Interop لتوقيع مستندات PDF باستخدام الرموز المادية. يجمع النهج بين الراحة والامتثال: تتولى GroupDocs جميع عمليات حزم PDF (حقول التوقيع، حساب التجزئة، الإدراج)، بينما يقوم الرمز المادي بالتوقيع التشفيري الفعلي.

⚠️ إشعار تنفيذ مبكر
يتم تقديم هذا الحل حاليًا كتنفيذ مبكر لاستخدام مفاتيح التوقيع الرقمية PKCS#11 مع GroupDocs.Signature.
بينما يتيح توقيع المستندات باستخدام الرموز المادية، نوصي بشدة بإجراء اختبارات إضافية في بيئتك الخاصة لضمان توافقه مع متطلبات الامتثال والأمان الخاصة بك.
نقدر كثيرًا ملاحظاتك، ونتائج الاختبار، واقتراحاتك للتحسين.

التحدي: ربط PKCS#11 بتوقيع PDF

دمج رموز PKCS#11 في سير عمل توقيع المستندات يواجه عدة تحديات غير بسيطة:

  1. التعقيد منخفض المستوى – تتطلب واجهة برمجة تطبيقات PKCS#11 (Cryptoki) إدارة الفتحات، الجلسات، المقابض، والسمات للعثور على المفتاح الخاص الصحيح.
  2. حزم مستوى PDF – توقيع PDF ليس مجرد توقيع للبايتات: يجب على المكتبة حساب التجزئات الصحيحة على نطاقات البايت المختارة، وتغليف التوقيعات في حاويات CMS/PKCS#7، وإدراج الطوابع الزمنية، وتضمين معلومات التحقق.
  3. اختلافات البائعين – قد تتطلب الرموز/الوحدات المختلفة من البائعين تعيين سمات مخصص أو وسائط إضافية.
  4. الامتثال وقابلية التدقيق – تحتاج الأنظمة الإنتاجية إلى معالجة PIN قوية، والتحكم في دورة حياة الجلسة، واستعادة الأخطاء، وتسجيل الأحداث.

يعالج هذا المشروع النموذجي هذه القضايا من خلال دمج واجهة ICustomSignHash في GroupDocs.Signature مع Pkcs11Interop لتفويض عملية التوقيع إلى الرمز المادي، بينما تتولى GroupDocs التعامل مع بنية PDF.

ما يفعله مشروع العينة

  • يوضح توقيع مستندات PDF باستخدام رموز PKCS#11 (مفتاح USB، بطاقة ذكية، أو HSM).
  • يدعم العودة إلى مخزن شهادات Windows: إذا تم تثبيت شهادة على Windows، يمكن للكود استخدامها بدلاً من ذلك.
  • ينفذ توقيع تجزئة مخصص: تقوم GroupDocs بحساب التجزئة؛ الرمز المادي يوقع التجزئة فقط.
  • يبقي المفتاح الخاص على الجهاز المادي في جميع الأوقات — لا يتم تصديره أبدًا.
  • ي encapsulates منطق الرمز المادي (الجلسة، البحث عن المفتاح، التوقيع) في Pkcs11DigitalSigner.cs
  • يوفر منطقًا مساعدًا في Helpers.cs (على سبيل المثال، البحث عن شهادة في مخزن Windows).
  • يتم تجميع الإعدادات في Settings.cs.
  • يعمل كتنفيذ مرجعي يمكنك تكييفه مع بيئتك.
Bridging PKCS#11 with PDF Signing

الإعداد والمتطلبات المسبقة

المتطلبات المسبقة

  • .NET 6.0 أو أعلى (أو .NET Framework 4.6.2)
  • مكتبة PKCS#11 صالحة (DLL) من مزود الرمز المادي الخاص بك
  • رمز مادي (مفتاح USB، بطاقة ذكية، أو HSM) يحتوي على شهادة صالحة
  • GroupDocs.Signature for .NET (نسخة تجريبية أو مرخصة)
  • مكتبة Pkcs11Interop

التثبيت

git clone https://github.com/groupdocs-signature/esign-documents-with-pkcs11-using-groupdocs-signature-dotnet.git
cd esign-documents-with-pkcs11-using-groupdocs-signature-dotnet
dotnet restore

افتح الحل في Visual Studio أو بيئة التطوير المفضلة لديك، وتأكد من حل جميع الاعتمادات.

نظرة عميقة على بنية المستودع

GroupDocs.Signature-for-.NET-PKCS11-Sample/
├── GroupDocs.Signature-for-.NET-PKCS11-Sample.csproj      # ملف المشروع
├── Program.cs                                             # نقطة الدخول وتدفق الاستخدام
├── Settings.cs                                            # إعدادات PKCS#11 / الرمز المادي
├── Helpers.cs                                             # وظائف مساعدة (مخزن Windows، تصفية الشهادات)
├── Pkcs11DigitalSigner.cs                                 # تنفيذ ICustomSignHash عبر PKCS#11
└── README.md                                              # شرح وتعليمات الاستخدام
  • Program.cs – يدير عملية التوقيع؛ يوضح كل من تدفق التوقيع القائم على الرمز المادي وتدفق شهادة Windows.
  • Settings.cs – يحتوي على ثوابت/نصوص نائبة لـ Pkcs11LibraryPath، TokenPin، وCertificateSubject.
  • Helpers.cs – يحتوي على كود للعثور على الشهادات في مخزن Windows حسب اسم الموضوع (يُستخدم في تدفق العودة).
  • Pkcs11DigitalSigner.cs – المنطق الأساسي: تحميل وحدة PKCS#11، فتح الجلسات، تحديد كائن المفتاح الخاص، توقيع التجزئة، وإرجاع X509Certificate2 أو تنفيذ رد نداء التوقيع.
  • README.md – يقدم نظرة عامة، تحديات، وتعليمات الاستخدام (التي تكملها هذه المدونة).

شرح الكود وجولة تفصيلية

Settings.cs

public static class Settings
{
    public const string Pkcs11LibraryPath = "<PKCS11_LIBRARY_PATH>";
    public const string TokenPin = "<TOKEN_PIN>";
    public const string CertificateSubject = "<CERT_SUBJECT>";
}

يفصل هذا الملف تفاصيل الإعداد لتسهيل استبدالها في بيئة النشر الخاصة بك.

Pkcs11DigitalSigner.cs — التدفق عالي المستوى

public class Pkcs11DigitalSigner : ICustomSignHash
{
    public byte[] SignHash(byte[] hash)
    {
        // This method is invoked by GroupDocs.Signature when it needs the token to sign a hash
        using (var pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, AppType.SingleThreaded))
        {
            // Load module, open session, login with PIN, find key and perform signing
        }
    }

    public X509Certificate2 GetCertificateFromPkcs11()
    {
        // Retrieves the public certificate from the token so the signing options can be configured
    }
}
  • SignHash هي الطريقة المركزية: تستقبل التجزئة التي حسبتها GroupDocs، ثم تستخدم واجهات PKCS#11 لتوقيعها.
  • GetCertificateFromPkcs11 تستخرج الشهادة العامة المخزنة في الرمز المادي لتكوين بيانات التوقيع بشكل صحيح.

Program.cs — تدفق الاستخدام

class Program
{
    static void Main()
    {
        string inputFile = "sample.pdf";
        string outputFile = "signed.pdf";

        // (1) PKCS#11 signing
        var tokenSigner = new Pkcs11DigitalSigner();
        var cert = tokenSigner.GetCertificateFromPkcs11();

        using (var signature = new Signature(inputFile))
        {
            var options = new DigitalSignOptions(cert)
            {
                Comments = "Signed with PKCS#11 token",
                SignTime = DateTime.Now,
                CustomSignHash = tokenSigner  // link token-based signing
            };
            signature.Sign(outputFile, options);
        }

        // (2) Windows certificate store fallback (optional)
        // var storeCert = Helpers.GetCertificateFromWindowsStore(Settings.CertificateSubject);
        // using (var signature2 = new Signature(inputFile))
        // {
        //     var options2 = new DigitalSignOptions(storeCert) { ... };
        //     signature2.Sign("signed_store.pdf", options2);
        // }
    }
}

نقاط رئيسية:

  • يتم تعيين خاصية CustomSignHash في DigitalSignOptions إلى tokenSigner، مما يتيح لـ GroupDocs تفويض عملية توقيع التجزئة الفعلية إلى الرمز المادي.
  • يُظهر التدفق الاحتياطي (المُعَلَّق) كيفية التحول إلى شهادة مخزن Windows عندما يكون الرمز المادي غير متاح.

حالات الاستخدام والسيناريوهات الواقعية

  • الولايات الهندية ومفاتيح USB الصادرة عن هيئة التصديق
    في الهند، تتطلب العديد من التوقيعات الإلكترونية القانونية أن تُخزن الشهادات في مفاتيح USB صادرة عن هيئات معتمدة. يتيح هذا العينة للتطبيقات (مثل بوابات المستندات أو البوابات الإلكترونية) التكامل مباشرة مع هذه المفاتيح.
  • سير عمل المستندات في المؤسسات
    للأنظمة الداخلية مثل إدارة العقود أو عمليات الموافقة، يضمن التوقيع المادي أن المستخدمين غير المصرح لهم لا يستطيعون تزوير توقيعات المستندات.
  • التوقيع القانوني / المتطلبات التنظيمية
    غالبًا ما تتطلب الحكومات والصناعات الخاضعة للرقابة أن تكون التوقيعات من مفاتيح تتحكم فيها الأجهزة المادية. يساعد هذا التكامل على تلبية متطلبات التدقيق والامتثال الصارمة.

الأخطاء الشائعة واستكشاف الأخطاء وإصلاحها

  • مسار المكتبة غير صحيح → يجب أن يتطابق مسار DLL الخاص بـ PKCS#11 مع وحدة المزود (مثل softhsm2.dll، cryptoki.dll).
  • قفل أو فشل PIN → قد تؤدي محاولات PIN الخاطئة المتكررة إلى قفل الرمز المادي؛ راجع سياسات المزود.
  • المفتاح غير موجود → تأكد من أن اسم الموضوع المقدم صحيح؛ يجب أن يحتوي الرمز المادي على شهادة بالموضوع المطابق.
  • عدم وجود برنامج تشغيل أو وسائط → بعض الرموز تتطلب تثبيت برامج تشغيل المزود قبل أن يتمكن Pkcs11Interop من التواصل.
  • مشكلات الخيوط → قد لا تكون عمليات PKCS#11 آمنة للمتعدد الخيوط؛ استخدم سياقًا أحادي الخيط ما لم يدعم المزود المتعدد.
  • انتهاء المهلة أو إعادة ضبط الجلسة → قد تتسبب العمليات الطويلة في إغلاق الجلسات أو انتهاء مهلتها؛ تأكد من معالجة الجلسة بشكل صحيح وإجراء التنظيف.

الأمان وأفضل الممارسات

  • لا تقم أبدًا بكتابة الأسرار الإنتاجية (PINs، مسارات المكتبة) في الشيفرة؛ استخدم إعدادات آمنة أو إدارة أسرار.
  • استخدم PINs قوية وقم بتدويرها وفقًا للسياسة المتاحة.
  • سجِّل العمليات والأخطاء (دون تسجيل PINs الحساسة).
  • قلل من جلسات الرمز المادي وسجِّل الخروج فور الانتهاء من التوقيع.
  • تحقق من صحة التوقيع بعد التوقيع (فحص السلسلة، الطابع الزمني).
  • اختبر عبر بيئات وأنواع رموز مختلفة (مفتاح USB / بطاقة ذكية / HSM).

الخطوات التالية والموارد

هل أنت مستعد لتجربتها بنفسك؟ استنسخ المستودع، حدّث القيم النائبة، وشغّل العينة.
المواضيع التي قد ترغب في استكشافها لاحقًا:

  • توقيع التجزئة المخصص (تفويض حساب التجزئة والتوقيع إلى الرمز المادي)
  • الطابع الزمني وتضمين LTV / DSS
  • التوقيع المتكرر (تعدد التوقيعات في مستند واحد)
  • التكامل مع خدمات HSM عن بُعد أو مخازن الرموز السحابية

روابط خارجية