Skip to content

Certyfikaty KSeF

03.02.2026

Wstęp

Certyfikat KSeF jest nośnikiem tożsamości podmiotu uwierzytelniającego (najczęściej identyfikowanej przez PESEL albo NIP, a w niektórych przypadkach przez fingerprint certyfikatu, który był wykorzystany do uwierzytelnienia w momencie wnioskowania o certyfikat KSeF). Certyfikat sam w sobie nie przenosi żadnych uprawnień KSeF i nie jest przypisany do żadnego kontekstu (np. NIP firmy / InternalId jednostki / NipVatUe). Uprawnienia są zarządzane i weryfikowane po stronie KSeF w oparciu o model uprawnień.

Endpointy do zarządzania certyfikatami są dostępne po uwierzytelnieniu. Operacje te dotyczą podmiotu uwierzytelnionego (właściciela certyfikatów) i nie są powiązane z kontekstem logowania, w którym uzyskano token dostępu. Oznacza to, że dany podmiot uwierzytelniony (np. osoba identyfikowana przez PESEL) ma dostęp do tego samego zbioru certyfikatów niezależnie od kontekstu, w jakim został uzyskany token dostępu.

Wniosek o wydanie certyfikatu KSeF może zostać złożony wyłącznie dla danych, które znajdują się w certyfikacie wykorzystanym do uwierzytelnienia. Na podstawie tych danych endpoint /certificates/enrollments/data zwraca dane identyfikacyjne, które muszą zostać użyte w żądaniu certyfikacyjnym.

Uwaga: wniosek o certyfikat KSeF może zostać złożony wyłącznie "we własnym imieniu" – dane identyfikacyjne do CSR są odczytywane z certyfikatu użytego do uwierzytelnienia, a ich modyfikacja powoduje odrzucenie wniosku.

Dostępne są dwa typy certyfikatów – każdy certyfikat może mieć tylko jeden typ (Authentication albo Offline). Nie jest możliwe wystawienie certyfikatu łączącego obie funkcje.

TypOpis
AuthenticationCertyfikat przeznaczony do uwierzytelniania w systemie KSeF.
keyUsage: Digital Signature (80)
OfflineCertyfikat przeznaczony wyłącznie do wystawiania faktur w trybie offline. Używany do potwierdzania autentyczności wystawcy i integralności faktury poprzez kod QR II. Nie umożliwia uwierzytelnienia.
keyUsage: Non-Repudiation (40)

Proces uzyskania certyfikatu

Proces aplikowania o certyfikat składa się z kilku etapów:

  1. Sprawdzenie dostępnych limitów,
  2. Pobranie danych do wniosku certyfikacyjnego,
  3. Wysłanie wniosku,
  4. Pobranie wystawionego certyfikatu,

1. Sprawdzenie limitów

Zanim klient API złoży wniosek o wydanie nowego certyfikatu zaleca się weryfikację limitu certyfikatów.

API udostępnia informacje na temat:

  • maksymalnej liczby certyfikatów, którą można dysponować,
  • liczby aktualnie aktywnych certyfikatów,
  • możliwości złożenia kolejnego wniosku.

GET /certificates/limits

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
CertificateLimitResponse certificateLimitResponse = await KsefClient
    .GetCertificateLimitsAsync(accessToken, CancellationToken);

Przykład w języku Java: CertificateIntegrationTest.java

java
CertificateLimitsResponse response = ksefClient.getCertificateLimits(accessToken);

2. Pobranie danych do wniosku certyfikacyjnego

Aby rozpocząć proces aplikowania o certyfikat KSeF, należy pobrać zestaw danych identyfikacyjnych, które system zwróci w odpowiedzi na wywołanie endpointu
GET /certificates/enrollments/data.

Dane te są odczytywane z certyfikatu użytego do uwierzytelnienia, którym może być:

  • kwalifikowany certyfikat osoby fizycznej – zawierający numer PESEL albo NIP,
  • kwalifikowany certyfikat organizacji (tzw. pieczęć firmowa) – zawierający numer NIP,
  • Profil Zaufany (ePUAP) – wykorzystywany przez osoby fizyczne, zawiera numer PESEL,
  • certyfikat wewnętrzny KSeF – wystawiany przez system KSeF, nie jest certyfikatem kwalifikowanym, ale jest honorowany w procesie uwierzytelniania.

System na tej podstawie zwraca komplet atrybutów DN (X.500 Distinguished Name), które muszą zostać użyte przy budowie żądania certyfikacyjnego (CSR). Modyfikacja tych danych spowoduje odrzucenie wniosku.

Uwaga: Pobranie danych certyfikacyjnych jest możliwe wyłącznie po uwierzytelnieniu z wykorzystaniem podpisu (XAdES). Uwierzytelnienie przy użyciu tokena systemowego KSeF nie pozwala na złożenie wniosku o certyfikat.

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
CertificateEnrollmentsInfoResponse certificateEnrollmentsInfoResponse =
    await KsefClient.GetCertificateEnrollmentDataAsync(accessToken, CancellationToken).ConfigureAwait(false);

Przykład w języku Java: CertificateIntegrationTest.java

java
CertificateEnrollmentsInfoResponse response = ksefClient.getCertificateEnrollmentInfo(accessToken);

Oto pełna lista pól, które mogą być zwrócone, przedstawiona w formie tabeli zawierającej OID:

OIDNazwa (ang.)OpisOsoba fizycznaPieczęć firmowa
2.5.4.3commonNameNazwa powszechna✔️✔️
2.5.4.4surnameNazwisko✔️
2.5.4.5serialNumberNumer seryjny (np. PESEL, NIP)✔️
2.5.4.6countryNameKod kraju (np. PL)✔️✔️
2.5.4.10organizationNameNazwa organizacji / firma✔️
2.5.4.42givenNameImię lub imiona✔️
2.5.4.45uniqueIdentifierUnikalny identyfikator (opcjonalny)✔️✔️
2.5.4.97organizationIdentifierIdentyfikator organizacji (np. NIP)✔️

Atrybut givenName może pojawić się wielokrotnie i zwracany jest w postaci listy wartości.

3. Przygotowanie CSR (Certificate Signing Request)

Aby złożyć wniosek o certyfikat KSeF, należy przygotować tzw. żądanie podpisania certyfikatu (CSR) w standardzie PKCS#10, w formacie DER, zakodowane w Base64. CSR zawiera:

  • informacje identyfikujące podmiot (DN – Distinguished Name),
  • klucz publiczny, który zostanie powiązany z certyfikatem.

Wymagania dotyczące klucza prywatnego użytego do podpisu CSR:

  • Typy dozwolone:

    • RSA (OID: 1.2.840.113549.1.1.1), długość klucza: 2048 bitów,
    • EC (klucze eliptyczne, OID: 1.2.840.10045.2.1), krzywa NIST P-256 (secp256r1).
  • Zalecane jest stosowanie kluczy EC.

  • Dozwolone algorytmy podpisu:

    • RSA PKCS#1 v1.5,
    • RSA PSS,
    • ECDSA (format podpisu zgodny z RFC 3279).
  • Dozwolone funkcje skrótu użyte do podpisu CSR:

    • SHA1,
    • SHA256,
    • SHA384,
    • SHA512.

Wszystkie dane identyfikacyjne (atrybuty X.509) powinny być zgodne z wartościami zwróconymi przez system w poprzednim kroku (/certificates/enrollments/data). Zmodyfikowanie tych danych spowoduje odrzucenie wniosku.

Przykład w języku C# (z użyciem ICryptographyService): KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
var (csr, key) = CryptographyService.GenerateCsrWithRSA(TestFixture.EnrollmentInfo);

Przykład w języku Java: CertificateIntegrationTest.java

java
CsrResult csr = defaultCryptographyService.generateCsrWithRsa(enrollmentInfo);
  • csrBase64Encoded – zawiera żądanie CSR zakodowane w formacie Base64, gotowe do wysłania do KSeF
  • privateKeyBase64Encoded – zawiera klucz prywatny powiązany z wygenerowanym CSR, zakodowany w Base64. Klucz ten będzie potrzebny do operacji podpisu przy użyciu certyfikatu.

Uwaga: Klucz prywatny powinien być przechowywany w sposób bezpieczny i zgodny z polityką bezpieczeństwa danej organizacji.

4. Wysłanie wniosku certyfikacyjnego

Po przygotowaniu żądania certyfikacyjnego (CSR) należy przesłać je do systemu KSeF za pomocą wywołania

POST /certificates/enrollments

W przesyłanym wniosku należy podać:

  • nazwę certyfikatu – widoczną później w metadanych certyfikatu, ułatwiającą identyfikację,
  • typ certyfikatuAuthentication lub Offline,
  • CSR w formacie PKCS#10 (DER), zakodowany jako ciąg Base64,
  • (opcjonalnie) validFrom – datę rozpoczęcia ważności. Jeśli nie zostanie wskazana, certyfikat będzie ważny od chwili jego wystawienia.

Upewnij się, że CSR zawiera dokładnie te same dane, które zostały zwrócone przez endpoint /certificates/enrollments/data.

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
SendCertificateEnrollmentRequest sendCertificateEnrollmentRequest = SendCertificateEnrollmentRequestBuilder
    .Create()
    .WithCertificateName(TestCertificateName)
    .WithCertificateType(CertificateType.Authentication)
    .WithCsr(csr)
    .WithValidFrom(DateTimeOffset.UtcNow.AddDays(CertificateValidityDays))
    .Build();

CertificateEnrollmentResponse certificateEnrollmentResponse = await KsefClient
    .SendCertificateEnrollmentAsync(sendCertificateEnrollmentRequest, accessToken, CancellationToken);

Przykład w języku Java: CertificateIntegrationTest.java

java
SendCertificateEnrollmentRequest request = new SendCertificateEnrollmentRequestBuilder()
        .withValidFrom(OffsetDateTime.now().toString())
        .withCsr(csr.csr())
        .withCertificateName("certificate")
        .withCertificateType(CertificateType.AUTHENTICATION)
        .build();

CertificateEnrollmentResponse response = ksefClient.sendCertificateEnrollment(request, accessToken);

W odpowiedzi otrzymasz referenceNumber, który umożliwia monitorowanie statusu wniosku oraz późniejsze pobranie wystawionego certyfikatu.

5. Sprawdzenie statusu wniosku

Proces wystawiania certyfikatu ma charakter asynchroniczny. Oznacza to, że system nie zwraca certyfikatu natychmiast po złożeniu wniosku, lecz umożliwia jego późniejsze pobranie po zakończeniu przetwarzania. Status wniosku należy okresowo sprawdzać, używając numeru referencyjnego (referenceNumber), który został zwrócony w odpowiedzi na wysłanie wniosku (/certificates/enrollments).

GET /certificates/enrollments/{referenceNumber}

Jeżeli wniosek certyfikacyjny zostanie odrzucony, w odpowiedzi otrzymamy informacje o błędzie.

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
CertificateEnrollmentStatusResponse certificateEnrollmentStatusResponse = await KsefClient
    .GetCertificateEnrollmentStatusAsync(TestFixture.EnrollmentReference, accessToken, CancellationToken);

Przykład w języku Java: CertificateIntegrationTest.java

java
CertificateEnrollmentStatusResponse response = ksefClient.getCertificateEnrollmentStatus(referenceNumber, accessToken);

Po uzyskaniu numeru seryjnego certyfikatu (certificateSerialNumber), możliwe jest pobranie jego zawartości i metadanych w kolejnych krokach procesu.

6. Pobieranie listy certyfikatów

System KSeF umożliwia pobranie treści wcześniej wystawionych certyfikatów wewnętrznych na podstawie listy numerów seryjnych. Każdy certyfikat zwracany jest w formacie DER, zakodowanym jako ciąg Base64.

POST /certificates/retrieve

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
CertificateListRequest certificateListRequest = new CertificateListRequest { CertificateSerialNumbers = TestFixture.SerialNumbers };

CertificateListResponse certificateListResponse = await KsefClient
    .GetCertificateListAsync(certificateListRequest, accessToken, CancellationToken);

Przykład w języku Java: CertificateIntegrationTest.java

java
CertificateListResponse certificateResponse = ksefClient.getCertificateList(new CertificateListRequest(List.of(certificateSerialNumber)), accessToken);

Każdy element odpowiedzi zawiera:

PoleOpis
certificateSerialNumberNumer seryjny certyfikatu
certificateNameNazwa certyfikatu nadana przy rejestracji
certificateTreść certyfikatu zakodowana w Base64 (format DER)
certificateTypeTyp certyfikatu (Authentication, Offline).

7. Pobieranie listy metadanych certyfikatów

Dostępna jest możliwość pobrania listy certyfikatów wewnętrznych złożonych przez dany podmiot. Dane te obejmują zarówno aktywne, jak i historyczne certyfikaty, wraz z ich statusem, zakresem ważności oraz identyfikatorami.

POST /certificates/query

Parametry filtrowania (opcjonalne):

  • status - status certyfikatu (Active, Blocked, Revoked, Expired)
  • expiresAfter - data końca ważności certyfikatu (opcjonalna)
  • name - nazwa certyfikatu (opcjonalny)
  • type - typ certyfikatu (Authentication, Offline) (opcjonalny)
  • certificateSerialNumber - numer seryjny certyfikatu (opcjonalny)
  • pageSize - liczba elementów na stronie (domyślnie 10)
  • pageOffset - numer strony wyników (domyślnie 0)

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificateMetadataListE2ETests.cs

csharp
var request = GetCertificateMetadataListRequestBuilder
    .Create()
    .WithCertificateSerialNumber(serialNumber)
    .WithName(name)
    .Build();
    CertificateMetadataListResponse certificateMetadataListResponse = await KsefClient
            .GetCertificateMetadataListAsync(accessToken, requestPayload, pageSize, pageOffset, CancellationToken);

Przykład w języku Java: CertificateIntegrationTest.java

java
QueryCertificatesRequest request = new CertificateMetadataListRequestBuilder().build();

CertificateMetadataListResponse response = ksefClient.getCertificateMetadataList(request, pageSize, pageOffset, accessToken);

W odpowiedzi otrzymamy metadane certyfikatów.

8. Unieważnianie certyfikatów

Certyfikat KSeF może zostać unieważniony tylko przez właściciela w przypadku kompromitacji klucza prywatnego, zakończenia jego użycia lub zmiany organizacyjnej. Po unieważnieniu certyfikat nie może być użyty do dalszego uwierzytelniania ani realizacji operacji w systemie KSeF. Unieważnienie realizowane jest na podstawie numeru seryjnego certyfikatu (certificateSerialNumber) oraz opcjonalnego powodu odwołania.

POST /certificates/{certificateSerialNumber}/revoke

Przykład w języku C#: KSeF.Client.Tests.Core\E2E\Certificates\CertificatesE2ETests.cs

csharp
CertificateRevokeRequest certificateRevokeRequest = RevokeCertificateRequestBuilder
        .Create()
        .WithRevocationReason(CertificateRevocationReason.KeyCompromise)
        .Build();

await ksefClient.RevokeCertificateAsync(request, certificateSerialNumber, accessToken, cancellationToken)
     .ConfigureAwait(false);

Przykład w języku Java: CertificateIntegrationTest.java

java
CertificateRevokeRequest request = new CertificateRevokeRequestBuilder()
        .withRevocationReason(CertificateRevocationReason.KEYCOMPROMISE)
        .build();

ksefClient.revokeCertificate(request, serialNumber, accessToken);

Po unieważnieniu certyfikat nie może zostać ponownie wykorzystany. Jeśli zajdzie potrzeba jego dalszego użycia, należy wystąpić o nowy certyfikat.