Przejdź do głównej zawartości
getnextpdf.com

Rozwiązywanie problemów z podpisami i znacznikami czasu

Te wpisy obejmują błędy podpisu zgłaszane przez NextPDF\Exception\SignatureException oraz NextPDF\Security\Signature\Exception\SignatureLevelUnreachableException. Każdy wpis wskazuje konkretną metodę fabryczną lub klasę, dzięki czemu przyczynę można potwierdzić na podstawie komunikatu i getContext(), zamiast ją zakładać.

Uwaga terminologiczna: silnik nie poświadcza, że podpis jest prawidłowy ani że dokument jest chroniony. Zgłasza błąd, który wykrył. Każde rozwiązanie traktuj jako krok prowadzący do usunięcia zgłoszonej przyczyny.

Wpis: nie można wygenerować poziomu PAdES „B-LT” ani „B-LTA”

Dział zatytułowany „Wpis: nie można wygenerować poziomu PAdES „B-LT” ani „B-LTA””
  • Objaw. SignatureException z końcówką komunikatu nextpdf/enterprise package is required for B-LT/B-LTA signatures.
  • Prawdopodobna przyczyna. Brakuje dostawcy funkcji walidacji długoterminowej. B-LT i B-LTA osadzają materiał unieważnień oraz archiwalny znacznik czasu, a taki dostawca jest dostępny w nextpdf/enterprise.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::ltvCapabilityMissing() generuje dokładnie ten komunikat. getContext() zwraca signature_level ustawione na poziom, dla którego podjęto próbę.
  • Rozwiązanie.
    1. Zainstaluj dostawcę, uruchamiając composer require nextpdf/enterprise.
    2. Ponownie wywołaj operację podpisywania.
    3. Jeśli nie możesz zainstalować dostawcy, zażądaj zamiast tego poziomu B-B lub B-T, który może wygenerować pakiet core.
  • Powiązane. Dokumentacja wyjątków.

Wpis: poziom podpisu jest nieosiągalny i wywołanie zostaje odrzucone

Dział zatytułowany „Wpis: poziom podpisu jest nieosiągalny i wywołanie zostaje odrzucone”
  • Objaw. SignatureLevelUnreachableException z komunikatem w postaci PAdES level "<x>" is unreachable (highest achievable: "<y>").
  • Prawdopodobna przyczyna. Żądany poziom zgodności wymaga infrastruktury, która nie jest dostępna w momencie podpisywania, najczęściej urzędu znaczników czasu dla poziomu B-T i wyższych. Silnik działa w trybie fail-closed: nie obniża po cichu poziomu, aby potem deklarować wyższy.
  • Dowody / diagnoza. getContext() zwraca requestedLevel, highestAchievableLevel oraz reason. Pole reason wskazuje brak w infrastrukturze. Jest to domyślne zachowanie fail-closed, wprowadzone po to, aby zapobiec powstaniu dokumentu deklarującego poziom, którego nie spełnia.
  • Rozwiązanie.
    1. Odczytaj pole reason, aby zidentyfikować brakującą infrastrukturę.
    2. Dostarcz brakujący komponent. Na przykład skonfiguruj urząd znaczników czasu i ponownie wywołaj operację.
    3. Aby celowo zaakceptować niższy poziom, przekaż allowDegradation: true do PadesOrchestrator. Wywołanie generuje wówczas highestAchievableLevel i zgłasza poziom, który wygenerowało.
  • Powiązane. Szyfrowanie i uprawnienia.

Wpis: klient urzędu znaczników czasu jest wymagany, ale go brakuje

Dział zatytułowany „Wpis: klient urzędu znaczników czasu jest wymagany, ale go brakuje”
  • Objaw. SignatureException z końcówką TSA client is required for level <x> but none was provided.
  • Prawdopodobna przyczyna. Żądanie poziomu B-T, B-LT lub B-LTA wymaga klienta urzędu znaczników czasu, a orkiestrator go nie otrzymał.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::tsaRequired() generuje ten komunikat; getContext() zawiera signature_level, którego dotyczyła próba.
  • Rozwiązanie.
    1. Skonfiguruj klienta urzędu znaczników czasu i przekaż go do orkiestratora.
    2. Ponownie wywołaj operację.
    3. Aby wygenerować poziom, który nie wymaga znacznika czasu, zażądaj B-B.
  • Powiązane. Dokumentacja wyjątków.

Wpis: adres URL punktu końcowego urzędu znaczników czasu jest pusty

Dział zatytułowany „Wpis: adres URL punktu końcowego urzędu znaczników czasu jest pusty”
  • Objaw. SignatureException z końcówką TSA endpoint URL is empty.
  • Prawdopodobna przyczyna. Klient urzędu znaczników czasu został utworzony z pustym adresem URL punktu końcowego.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::tsaUrlEmpty() generuje ten komunikat. Jest to wada konfiguracji, a nie awaria sieci.
  • Rozwiązanie.
    1. Ustaw niepusty adres URL punktu końcowego w kliencie urzędu znaczników czasu, na przykład https://timestamp.example.com/tsa.
    2. Jeśli żądany poziom nie wymaga znacznika czasu, usuń zamiast tego podłączenie klienta urzędu znaczników czasu.
    3. Ponownie wywołaj operację.
  • Powiązane. Dokumentacja wyjątków.

Wpis: znacznik czasu podpisu nie wiąże się z podpisem (niezgodność odcisku)

Dział zatytułowany „Wpis: znacznik czasu podpisu nie wiąże się z podpisem (niezgodność odcisku)”
  • Objaw. TsaTokenVerificationException z krokiem Step::ImprintBinding, z końcówką komunikatu, taką jak TSTInfo messageImprint does not bind the SignerInfo signature value — token opatruje znacznikiem czasu inne bajty niż podpis, który rzekomo ma obejmować.
  • Prawdopodobna przyczyna. Odcisk komunikatu (message imprint) znacznika czasu podpisu nie jest skrótem wartości podpisu SignerInfo, do której jest dołączony. Najczęstszą, łagodną przyczyną jest dokument wygenerowany przez wersję NextPDF sprzed poprawki wiązania odcisku z RFC 3161 Appendix A: te wersje obliczały skrót z innych danych wejściowych, więc ich znaczniki czasu B-T nie mogą udowodnić powiązania rygorystycznemu weryfikatorowi. Inne przyczyny to podmieniony lub zmanipulowany token znacznika czasu albo token, którego odcisk korzysta z SHA-1 lub nierozpoznanego algorytmu (odrzucanego w trybie fail-closed dla tego sprawdzenia).
  • Dowody / diagnoza. Sprawdzeniem jest dedykowany krok verifySignatureTimestamp() (Step::ImprintBinding), który przyjmuje wartość podpisu jako wymagane dane wejściowe, dzięki czemu nigdy nie może zostać po cichu pominięty. Odrzuca w trybie fail-closed przy pustych danych wejściowych, nierozpoznanym identyfikatorze obiektu odcisku, odcisku SHA-1, nieprawidłowej strukturze odcisku lub niezgodności skrótu.
  • Rozwiązanie.
    1. Jeśli dokument został wygenerowany przez wersję silnika sprzed poprawki, podpisz go ponownie i ponownie opatrz znacznikiem czasu przy użyciu aktualnej wersji. Odcisk znacznika czasu jest niezmiennym dowodem i nie da się go naprawić w miejscu. Jest to celowa, trwała zmiana łamiąca zgodność (zobacz wpis „Security” w pliku CHANGELOG dotyczący poprawki zgodności messageImprint znacznika czasu podpisu PAdES).
    2. Jeśli dokument jest aktualny, potraktuj niezgodność jako rzeczywisty błąd wiązania: znacznik czasu nie obejmuje tego podpisu, więc nie polegaj na nim dla poziomu B-T.
    3. W przypadku algorytmu odcisku SHA-1 lub nieznanego znacznik czasu nie może udowodnić powiązania niezależnie od wieku dokumentu; uzyskaj znacznik czasu, który używa obsługiwanego skrótu odcisku (domyślnie SHA-256).
  • Powiązane. Dokumentacja wyjątków.
  • Objaw. SignatureException z końcówką no /Contents <…> field found in PDF buffer (signature placeholder missing).
  • Prawdopodobna przyczyna. Etap podpisywania otrzymał bufor bez zarezerwowanego kontenera podpisu, więc nie ma miejsca, w którym można zapisać podpis.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::signatureContentsNotFound() generuje ten komunikat.
  • Rozwiązanie.
    1. Upewnij się, że pole podpisu i jego symbol zastępczy są zapisane przed uruchomieniem etapu podpisywania.
    2. Ponownie uruchom potok, aby symbol zastępczy istniał w momencie rozpoczęcia podpisywania.
  • Powiązane. Dokumentacja wyjątków.

Wpis: status unieważnienia jest nieznany (responder OCSP odmówił)

Dział zatytułowany „Wpis: status unieważnienia jest nieznany (responder OCSP odmówił)”
  • Objaw. SignatureException z końcówką OCSP responder returned non-successful OCSPResponseStatus "<status>".
  • Prawdopodobna przyczyna. Responder Online Certificate Status Protocol (OCSP) nie zwrócił statusu successful, więc nie wygenerował żadnego potwierdzenia unieważnienia. Silnik stosuje się do RFC 6960 §4.2.1, które cytuje w kodzie źródłowym: wypełniona treść odpowiedzi jest dozwolona wyłącznie dla statusu successful (0). Silnik odmawia traktowania odrzuconej odpowiedzi jako wyniku potwierdzającego zaufanie.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::nonSuccessfulOcspResponseStatus() generuje ten komunikat i podaje zgłoszony status, na przykład tryLater lub internalError. Zarezerwowany albo nieznany bajt statusu generuje natomiast SignatureException::reservedOcspResponseStatus().
  • Rozwiązanie.
    1. Zidentyfikuj status w komunikacie. W przypadku statusu przejściowego, takiego jak tryLater, ponów pobranie unieważnienia później.
    2. W przypadku unauthorized lub malformedRequest zweryfikuj adres URL żądania OCSP oraz certyfikat, którego oczekuje responder.
    3. Nie wyciszaj błędu, aby uzyskać artefakt B-LT lub B-LTA; potwierdzenie unieważnienia jest częścią tego poziomu.
  • Powiązane. Dokumentacja wyjątków.

Wpis: nie udaje się zdekodować wpisu łańcucha certyfikatów

Dział zatytułowany „Wpis: nie udaje się zdekodować wpisu łańcucha certyfikatów”
  • Objaw. SignatureException z końcówką failed to base64-decode PEM body — input is not valid PEM.
  • Prawdopodobna przyczyna. Wpis łańcucha certyfikatów nie ma prawidłowego formatu Privacy-Enhanced Mail (PEM), zwykle z powodu obcięcia, błędnego znaku lub binarnego bloku Distinguished Encoding Rules (DER) dostarczonego tam, gdzie oczekiwano PEM.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::pemDecodingFailed() generuje ten komunikat podczas budowania łańcucha.
  • Rozwiązanie.
    1. Sprawdź każdy certyfikat w łańcuchu pod kątem błędnych znaków lub obcięcia.
    2. Ponownie wyeksportuj w formacie PEM certyfikat, którego dotyczy problem.
    3. Ponownie wywołaj operację podpisywania.
  • Powiązane. Szyfrowanie i uprawnienia.
  • Objaw. SignatureException z końcówką expected private key of type "<x>" for the configured algorithm but got "<y>".
  • Prawdopodobna przyczyna. Wczytany klucz prywatny nie pasuje do skonfigurowanego algorytmu podpisu, na przykład klucz Rivest-Shamir-Adleman (RSA) przy wybranym Elliptic Curve Digital Signature Algorithm (ECDSA).
  • Dowody / diagnoza. Metoda fabryczna SignatureException::unexpectedKeyType() generuje ten komunikat i podaje zarówno oczekiwaną, jak i rzeczywistą klasę klucza.
  • Rozwiązanie.
    1. Sprawdź, czy certyfikat i para kluczy pasują do wybranego algorytmu.
    2. Zmień algorytm tak, aby pasował do klucza, albo wczytaj klucz, który pasuje do algorytmu.
    3. Ponownie wywołaj operację podpisywania.
  • Powiązane. Dokumentacja wyjątków.

Wpis: klucz lub materiał podpisu Ed25519 jest zniekształcony

Dział zatytułowany „Wpis: klucz lub materiał podpisu Ed25519 jest zniekształcony”
  • Objaw. SignatureException z końcówką wskazującą niezgodność długości Ed25519 — na przykład Ed25519 signature length <n> ≠ expected 64 bytes lub Ed25519 round-trip self-verify failed.
  • Prawdopodobna przyczyna. Kompilacja biblioteki kryptograficznej w środowisku zwróciła klucz lub materiał podpisu o nieprawidłowej długości albo świeżo wygenerowany podpis nie przeszedł weryfikacji przy użyciu własnego klucza publicznego. Silnik cytuje w kodzie źródłowym RFC 8032 §3.4, które ustala długość odłączonego podpisu Ed25519 na 64 bajty. Silnik przerywa działanie zamiast zwracać materiał, którego nie może samodzielnie zweryfikować.
  • Dowody / diagnoza. Odpowiednie metody fabryczne to SignatureException::ed25519SignatureMalformed(), ::ed25519RoundTripVerifyFailed(), ::ed25519KeyParseFailed(), ::ed25519SeedInvalid(), ::ed25519SecretKeyMalformed() oraz ::ed25519PublicKeyInvalid(). Każda z nich podaje zaobserwowaną długość.
  • Rozwiązanie.
    1. Zainstaluj ponownie rozszerzenie PHP libsodium; okrojona lub uszkodzona kompilacja jest udokumentowaną przyczyną materiału o nieprawidłowej długości.
    2. Potwierdź, że klucz jest kluczem Ed25519, a OpenSSL ma wersję 1.1.1 lub nowszą.
    3. Ponownie wywołaj operację podpisywania.
  • Powiązane. Dokumentacja wyjątków.

Wpis: słownik archiwalnego znacznika czasu nie został wyemitowany

Dział zatytułowany „Wpis: słownik archiwalnego znacznika czasu nie został wyemitowany”
  • Objaw. SignatureException z końcówką no /Type /DocTimeStamp dictionary was emitted into the PDF buffer.
  • Prawdopodobna przyczyna. Pętla archiwizacji B-LTA wykonała się, ale słownik znacznika czasu dokumentu nigdy nie trafił do bufora. Artefakt byłby niedokończonym B-LTA, więc silnik odmawia jego zwrócenia.
  • Dowody / diagnoza. Metoda fabryczna SignatureException::documentTimestampNotEmitted() generuje ten komunikat. Ten błąd warunku końcowego jest zgłaszany na etapie finalizacji.
  • Rozwiązanie.
    1. Potraktuj wynik jako odrzucony; nie wysyłaj częściowego artefaktu.
    2. Ponownie uruchom potok B-LTA z osiągalnym urzędem znaczników czasu.
    3. Jeśli błąd się powtarza, dołącz getContext() oraz powiązany poprzedni wyjątek do zgłoszenia usterki.
  • Powiązane. Dokumentacja wyjątków.
  • Te metody fabryczne ustawiają cert_info na podmiot lub odcisk palca tylko wtedy, gdy taka informacja jest dostępna; puste cert_info jest oczekiwane w przypadku błędów funkcji i konfiguracji.
  • Żądanie poziomu B-LT lub B-LTA bez skonfigurowanego klienta Hypertext Transfer Protocol (HTTP) zgłasza SignatureException::httpClientMissing(); pobranie unieważnienia wymaga przekazania orkiestratorowi klienta PHP Standards Recommendation (PSR)-18.
  • Certyfikat oparty na sprzętowym module bezpieczeństwa (HSM) bez zaimplementowanego obiektu podpisującego zgłasza SignatureException::hsmSignerMissing(); podłącz obiekt podpisujący do certyfikatu przed podpisaniem.

Słownik: poziom PAdES · potwierdzenie unieważnienia