Wprowadzenie i Motywacja

Podczas implementacji podpisów cyfrowych w systemach klasy enterprise, bezpieczeństwo jest nie do negocjacji.
Przechowywanie certyfikatu w lokalnym pliku PFX lub P12 jest wygodne, ale naraża klucz prywatny na wyodrębnienie lub naruszenie. Natomiast tokeny sprzętowe PKCS#11 (takie jak klucze USB, karty inteligentne i HSM) przechowują klucze wewnątrz odpornej na manipulacje granicy, zapewniając, że nigdy nie opuszczą urządzenia.

Ten wpis demonstruje, jak używać GroupDocs.Signature for .NET wraz z Pkcs11Interop do podpisywania dokumentów PDF przy użyciu tokenów sprzętowych. Podejście łączy wygodę i zgodność: GroupDocs zajmuje się całym pakowaniem na poziomie PDF (pola podpisu, obliczanie skrótu, osadzanie), podczas gdy token wykonuje faktyczny kryptograficzny podpis.

⚠️ Wczesne powiadomienie o implementacji
To rozwiązanie jest obecnie udostępniane jako wczesna implementacja użycia kluczy USB PKCS#11 z GroupDocs.Signature.
Choć umożliwia podpisywanie dokumentów tokenami sprzętowymi, zdecydowanie zalecamy przeprowadzenie dodatkowych testów w własnym środowisku, aby upewnić się, że spełnia ono wymagania zgodności i bezpieczeństwa.
Będziemy bardzo wdzięczni za wszelkie opinie, wyniki testów oraz sugestie dotyczące ulepszeń.

Wyzwanie: Łączenie PKCS#11 z podpisywaniem PDF

Integracja tokenów PKCS#11 w procesy podpisywania dokumentów niesie ze sobą kilka niebanalnych wyzwań:

  1. Złożoność niskiego poziomu – API PKCS#11 (Cryptoki) wymaga zarządzania slotami, sesjami, uchwytami i atrybutami, aby odnaleźć właściwy klucz prywatny.
  2. Pakowanie na poziomie PDF – Podpisanie PDF to nie tylko podpisywanie bajtów: biblioteka musi obliczyć poprawne skróty nad wybranymi zakresami bajtów, opakować podpisy w kontenery CMS/PKCS#7, dołączyć znaczniki czasu i osadzić informacje weryfikacyjne.
  3. Różnice producentów – Różne tokeny/module dostawców mogą wymagać niestandardowego mapowania atrybutów lub dodatkowego oprogramowania pośredniczącego.
  4. Zgodność i audytowalność – Systemy produkcyjne potrzebują solidnego zarządzania PIN-em, kontroli cyklu życia sesji, odzyskiwania po błędach i logowania.

Ten przykładowy projekt rozwiązuje te problemy, łącząc interfejs ICustomSignHash w GroupDocs.Signature z Pkcs11Interop, aby przenieść podpisywanie na token, pozostawiając GroupDocs obsługę struktury PDF.

Co robi przykładowy projekt

  • Demonstruje podpisywanie dokumentów PDF przy użyciu tokenów PKCS#11 (klucz USB, karta inteligentna, HSM).
  • Obsługuje zapasowy dostęp do magazynu certyfikatów Windows: jeśli certyfikat jest zainstalowany w systemie Windows, kod może go użyć zamiast tokena.
  • Implementuje niestandardowe podpisywanie skrótu: GroupDocs oblicza skrót; token podpisuje jedynie skrót.
  • Przechowuje klucz prywatny na sprzęcie przez cały czas — nigdy nie jest eksportowany.
  • Zawiera logikę tokena (sesja, wyszukiwanie klucza, podpisywanie) w pliku Pkcs11DigitalSigner.cs
  • Dostarcza pomocniczą logikę w Helpers.cs (na przykład wyszukiwanie certyfikatu w magazynie Windows).
  • Konfiguracja scentralizowana w Settings.cs.
  • Działa jako referencyjna implementacja, którą możesz dostosować do swojego środowiska.
Bridging PKCS#11 with PDF Signing

Konfiguracja i wymagania wstępne

Prerequisites

  • .NET 6.0 lub nowszy (lub .NET Framework 4.6.2)
  • Ważna biblioteka PKCS#11 (DLL) od dostawcy tokena
  • Token sprzętowy (klucz USB, karta inteligentna lub HSM) z ważnym certyfikatem
  • GroupDocs.Signature for .NET (wersja próbna lub licencjonowana)
  • Biblioteka Pkcs11Interop

Installation

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

Otwórz rozwiązanie w Visual Studio lub preferowanym IDE, upewnij się, że zależności są rozwiązane.

Szczegółowa struktura repozytorium

    GroupDocs.Signature-for-.NET-PKCS11-Sample/
    ├── GroupDocs.Signature-for-.NET-PKCS11-Sample.csproj      # Plik projektu
    ├── Program.cs                                             # Punkt wejścia i przepływ użycia
    ├── Settings.cs                                            # Konfiguracja PKCS#11 / tokena
    ├── Helpers.cs                                             # Funkcje pomocnicze (magazyn Windows, filtrowanie certyfikatów)
    ├── Pkcs11DigitalSigner.cs                                 # Implementuje ICustomSignHash przy użyciu PKCS#11
    └── README.md                                              # Wyjaśnienie i instrukcje użycia
  • Program.cs – koordynuje podpisywanie; demonstruje zarówno przepływ oparty na tokenie, jak i na certyfikacie Windows.
  • Settings.cs – zawiera stałe/miejsca zastępcze dla Pkcs11LibraryPath, TokenPin i CertificateSubject.
  • Helpers.cs – zawiera kod służący do znajdowania certyfikatów w magazynie Windows po nazwie podmiotu (używany w trybie awaryjnym).
  • Pkcs11DigitalSigner.cs – logika podstawowa: ładowanie modułu PKCS#11, otwieranie sesji, lokalizowanie obiektu klucza prywatnego, podpisywanie skrótu oraz zwracanie X509Certificate2 lub implementacji wywołania zwrotnego podpisu.
  • README.md – zawiera przegląd, wyzwania i instrukcje użycia (które uzupełnia ten blog).

Wyjaśnienie kodu i omówienie

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>";
}

To oddziela szczegóły konfiguracji, aby można je było łatwo podmienić w środowisku wdrożeniowym.

Pkcs11DigitalSigner.cs — przepływ wysokiego poziomu

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 jest centralną metodą: otrzymuje skrót obliczony przez GroupDocs, a następnie przy użyciu API PKCS#11 podpisuje go.
  • GetCertificateFromPkcs11 pobiera certyfikat (z kluczem publicznym) przechowywany w tokenie, aby metadane podpisu były prawidłowe.

Program.cs — przepływ użycia

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);
        // }
    }
}

Kluczowe punkty:

  • Właściwość CustomSignHash w DigitalSignOptions jest ustawiona na tokenSigner, co pozwala GroupDocs delegować rzeczywiste podpisywanie skrótu na token.
  • Przepływ awaryjny (zakomentowany) pokazuje, jak przełączyć się na certyfikat z magazynu Windows, gdy token sprzętowy jest niedostępny.

Przypadki użycia i scenariusze rzeczywiste

  • Indie i dongle z certyfikatami wydanymi przez CA
    W Indiach wiele prawnie wiążących e-podpisów wymaga certyfikatów przechowywanych w kluczach USB wydanych przez certyfikowane organy. Ten przykład umożliwia aplikacjom (np. bramkom dokumentów, portalom) bezpośrednią integrację z takimi kluczami.

  • Korporacyjne przepływy dokumentów
    Dla wewnętrznych systemów, takich jak zarządzanie umowami czy procesy zatwierdzania, podpisywanie sprzętowe zapewnia, że nieuprawnieni użytkownicy nie mogą fałszować podpisów dokumentów.

  • Podpisy prawne / zgodne z wymogami
    Rządy i regulowane branże często wymagają, aby podpisy pochodziły z kluczy kontrolowanych sprzętowo. Ta integracja pomaga spełnić surowe wymogi audytu i zgodności.

Typowe pułapki i rozwiązywanie problemów

  • Niepoprawna ścieżka do biblioteki → Ścieżka do DLL PKCS#11 musi odpowiadać modułowi dostawcy tokena (np. softhsm2.dll, cryptoki.dll).
  • Blokada lub niepowodzenie PIN → Wielokrotne błędne wprowadzenie PIN‑u może zablokować token; sprawdź politykę dostawcy.
  • Klucz nie znaleziony → Upewnij się, że podano właściwy podmiot certyfikatu; token musi zawierać certyfikat z pasującym podmiotem.
  • Brak sterownika lub oprogramowania pośredniczącego → Niektóre tokeny wymagają zainstalowanych sterowników dostawcy, zanim Pkcs11Interop będzie mógł się z nimi komunikować.
  • Problemy z wątkowością → Operacje PKCS#11 mogą nie być wątkowo bezpieczne; używaj kontekstu jednowątkowego, chyba że dostawca obsługuje wielowątkowość.
  • Timeouty lub resetowanie sesji → Długie operacje mogą powodować zamknięcie lub wygaśnięcie sesji; zapewnij prawidłowe zarządzanie sesjami i ich czyszczenie.

Bezpieczeństwo i najlepsze praktyki

  • Nigdy nie wpisuj na stałe w kodzie produkcyjnych tajemnic (PIN‑y, ścieżki do bibliotek); używaj bezpiecznej konfiguracji lub zarządzania sekretami.
  • Używaj silnych PIN‑ów i zmieniaj je zgodnie z polityką.
  • Loguj operacje i błędy (bez logowania wrażliwych PIN‑ów).
  • Ogranicz sesje tokena i wyloguj się natychmiast po podpisaniu.
  • Waliduj podpis po jego utworzeniu (sprawdzanie łańcucha, znacznik czasu).
  • Testuj w różnych środowiskach i typach tokenów (klucz USB/karta inteligentna/HSM).

Kolejne kroki i zasoby

Gotowy, aby wypróbować sam? Sklonuj repozytorium, zaktualizuj miejsca zastępcze i uruchom przykład. Tematy, które możesz chcieć zgłębić dalej:

  • Niestandardowe podpisywanie skrótu (delegowanie skrótu + podpisywania do tokena)
  • Znacznikowanie czasu i osadzanie LTV / DSS
  • Iteracyjne podpisywanie (wiele podpisów w jednym dokumencie)
  • Integracja z zdalnymi usługami HSM lub chmurowymi magazynami tokenów

Linki zewnętrzne