Serwis używa plików cookies, aby mógł lepiej spełniać Państwa oczekiwania. Podczas korzystania z serwisu pliki te są zapisywane w pamięci urządzenia. Zapisywanie plików cookies można zablokować, zmieniając ustawienia przeglądarki. Więcej o plikach cookies możesz przeczytać tutaj.

Autorzy więcej

AUDYT TECHNICZNY KSeF — SZYFROWANIE E2E FAKTURY XML

MF zaprojektowało ochronę treści prawnej faktury (XML), jednocześnie nie chroniąc danych biznesowych o wysokiej wartości wywiadowczej (metadanych JSON). Z perspektywy wywiadu gospodarczego metadane mogą być wartościowsze niż sama treść dokumentu — umożliwiają masową analizę przepływów finansowych między podmiotami bez konieczności odczytywania treści faktur.

Audyt techniczny · Marzec 2026

Szyfrowanie E2E treści faktury XML w KSeF

Odpowiedź na Pytanie 2 z interwencji poselskiej
Posłowie Skalik i Zawiślak · Ministerstwo Finansów · 20 lutego 2026 r.
Przedmiot audytu api.ksef.mf.gov.pl — KSeF 2.0, środowisko produkcyjne
Metoda Analiza specyfikacji OpenAPI + dokumentacji technicznej MF
Data Marzec 2026
Autor Grzegorz GPS Świderski
Interwencja poselska Posłowie Skalik i Zawiślak, 20 lutego 2026 r.

1. Kontekst i pytanie audytowe

Niniejszy audyt stanowi odpowiedź na Pytanie 2 z interwencji poselskiej złożonej przez posłów Skalika i Zawiślaka w Ministerstwie Finansów dnia 20 lutego 2026 r. Poprzednie dwa audyty wykazały:

Pytanie 2 z interwencji poselskiej
Czy Ministerstwo Finansów potwierdza, że treść faktury przekazywanej do systemu KSeF w formacie XML podlega szyfrowaniu aplikacyjnemu end-to-end, w wyniku czego pozostaje nieczytelna dla podmiotów pośredniczących w transmisji — w tym operatora WAF — nawet po terminacji połączenia TLS, oraz czy jakikolwiek podmiot pośredniczący posiada dostęp do kluczy kryptograficznych lub równoważnych mechanizmów umożliwiających odszyfrowanie tej treści?

2. Metodologia i zakres

Audyt oparty jest wyłącznie na publicznie dostępnych, oficjalnych źródłach opublikowanych przez Ministerstwo Finansów. Nie zastosowano żadnych metod ingerencji w system.

Krok Źródło Cel Wynik
1 open-api.json (GitHub MF) Lista endpointów i schematów API
2 open-api.json — schemat SendInvoiceRequest Struktura żądania wysyłki faktury XML
3 sesja-interaktywna.md (GitHub MF) Mechanizm kryptograficzny sesji online
4 sesja-wsadowa.md (GitHub MF) Mechanizm kryptograficzny sesji wsadowej
5 open-api.json — schemat EncryptionInfo Schemat klucza szyfrującego

3. Krok 1 — Pobranie specyfikacji OpenAPI i identyfikacja endpointów

3.1. Komenda

PowerShell
$specUrl = "https://raw.githubusercontent.com/CIRFMF/ksef-docs/main/open-api.json"
$raw = Invoke-WebRequest -Uri $specUrl | Select-Object -ExpandProperty Content
$spec = $raw | ConvertFrom-Json

Write-Host "=== ŚCIEŻKI API ==="
$spec.paths.PSObject.Properties.Name | Sort-Object

Write-Host "`n=== SCHEMATY ZWIĄZANE Z WYSYŁKĄ ==="
$spec.components.schemas.PSObject.Properties.Name |
Select-String -Pattern 'Invoice|Send|Encrypt|Payload|Hash' -CaseSensitive:$false

3.2. Wynik (fragment)

Wynik
=== ŚCIEŻKI API ===
/sessions/online
/sessions/online/{referenceNumber}/invoices
/sessions/batch
/invoices/query/metadata
/security/public-key-certificates
...

=== SCHEMATY ZWIĄZANE Z WYSYŁKĄ ===
EncryptionInfo
SendInvoiceRequest
SendInvoiceResponse
InvoiceMetadata
InvoicePackage
InvoicePackagePart
Sha256HashBase64

3.3. Interpretacja

Specyfikacja OpenAPI API KSeF 2.0 jest publicznie dostępna w oficjalnym repozytorium GitHub Ministerstwa Finansów (CIRFMF/ksef-docs). Zidentyfikowano dwa krytyczne schematy: SendInvoiceRequest (żądanie wysyłki faktury) oraz EncryptionInfo (informacje o kluczu szyfrującym). Ich szczegółowa analiza następuje w kolejnych krokach.


4. Krok 2 — Schemat żądania wysyłki faktury XML (SendInvoiceRequest)

4.1. Komenda

PowerShell
$specUrl = "https://raw.githubusercontent.com/CIRFMF/ksef-docs/main/open-api.json"
$spec = Invoke-WebRequest -Uri $specUrl | Select-Object -ExpandProperty Content | ConvertFrom-Json

Write-Host "=== SCHEMAT: SendInvoiceRequest ==="
$spec.components.schemas.SendInvoiceRequest | ConvertTo-Json -Depth 10

4.2. Wynik

Wynik
{
"required": [
"encryptedInvoiceContent",
"encryptedInvoiceHash",
"encryptedInvoiceSize",
"invoiceHash",
"invoiceSize"
],
"properties": {
"invoiceHash": {
"description": "Skrót SHA256 oryginalnej faktury, zakodowany w formacie Base64."
},
"encryptedInvoiceHash": {
"description": "Skrót SHA256 zaszyfrowanej faktury, zakodowany w formacie Base64."
},
"encryptedInvoiceContent": {
"type": "string",
"description": "Faktura zaszyfrowana algorytmem AES-256-CBC z dopełnianiem PKCS#7
(kluczem przekazanym przy otwarciu sesji), zakodowana w formacie Base64."
,
"format": "byte"
}
}
}

4.3. Interpretacja

Kontrakt API nie zawiera pola z jawną treścią faktury XML. Jedynym polem przenoszącym treść dokumentu jest encryptedInvoiceContent, opisane w specyfikacji oficjalnie przez MF jako:

Opis pola encryptedInvoiceContent w specyfikacji OpenAPI MF „Faktura zaszyfrowana algorytmem AES-256-CBC z dopełnianiem PKCS#7 (kluczem przekazanym przy otwarciu sesji), zakodowana w formacie Base64."

API KSeF jest zaprojektowane tak, aby nigdy nie przyjmować jawnego XML faktury. Jedyną legalną formą przesłania faktury jest jej zaszyfrowana wersja. Mechanizm szyfrowania jest architektonicznie wymuszony przez kontrakt API.


5. Krok 3 — Mechanizm kryptograficzny sesji interaktywnej

5.1. Komenda

PowerShell
$url = "https://raw.githubusercontent.com/CIRFMF/ksef-docs/main/sesja-interaktywna.md"
$content = Invoke-WebRequest -Uri $url | Select-Object -ExpandProperty Content
$content | Select-String -Pattern 'encrypt|szyfr|klucz|key|AES|RSA' -CaseSensitive:$false -Context 2,2

5.2. Wynik — kluczowy fragment dokumentacji MF

sesja-interaktywna.md (GitHub CIRFMF/ksef-docs)
Przed otwarciem sesji oraz wysłaniem faktur wymagane jest:

* wygenerowanie klucza symetrycznego o długości 256 bitów i wektora inicjującego
o długości 128 bitów (IV), dołączanego jako prefiks do szyfrogramu,
* zaszyfrowanie dokumentu algorytmem AES-256-CBC z dopełnianiem PKCS#7,
* zaszyfrowanie klucza symetrycznego algorytmem RSAES-OAEP
(padding OAEP z funkcją MGF1 opartą na SHA-256 oraz skrótem SHA-256),
przy użyciu klucza publicznego KSeF Ministerstwa Finansów.

-- Przykład C# (biblioteka referencyjna MF):
byte[] encryptedInvoice = cryptographyService.EncryptBytesWithAES256(
invoice, encryptionData.CipherKey, encryptionData.CipherIv);

SendInvoiceRequest sendOnlineInvoiceRequest = SendInvoiceOnlineSessionRequestBuilder
.Create()
.WithEncryptedDocumentContent(Convert.ToBase64String(encryptedInvoice))
.Build();

5.3. Interpretacja

Dokumentacja techniczna MF opisuje trójstopniowy mechanizm kryptograficzny wykonywany po stronie klienta, przed wysyłką jakichkolwiek danych do sieci:

Etap Operacja Szczegóły techniczne
1 Generowanie klucza Klient generuje lokalnie losowy klucz AES-256 i wektor IV — nigdy nie opuszczają klienta w postaci jawnej
2 Szyfrowanie XML Faktura XML szyfrowana lokalnie: AES-256-CBC/PKCS#7. W sieci pojawia się wyłącznie zaszyfrowany blob
3 Ochrona klucza AES Klucz AES szyfrowany kluczem publicznym RSA-OAEP/SHA-256 MF. Odszyfrowanie możliwe wyłącznie przez posiadacza klucza prywatnego MF
Wniosek kroku 3
Treść XML faktury jest szyfrowana po stronie klienta przed wysyłką. Imperva po terminacji TLS widzi w ciele żądania wyłącznie zaszyfrowany ciąg bajtów Base64. Odczytanie XML jest możliwe wyłącznie dla posiadacza klucza prywatnego RSA Ministerstwa Finansów.

6. Krok 4 — Mechanizm kryptograficzny sesji wsadowej

6.1. Komenda

PowerShell
$url = "https://raw.githubusercontent.com/CIRFMF/ksef-docs/main/sesja-wsadowa.md"
$content = Invoke-WebRequest -Uri $url | Select-Object -ExpandProperty Content
$content | Select-String -Pattern 'AES|RSA|zaszyfrowa|klucz|encrypt' -CaseSensitive:$false -Context 1,2

6.2. Wynik — kluczowy fragment dokumentacji MF

sesja-wsadowa.md (GitHub CIRFMF/ksef-docs)
Przed otwarciem sesji oraz wysłaniem faktur wymagane jest:
* wygenerowanie klucza symetrycznego o długości 256 bitów i wektora inicjującego
o długości 128 bitów (IV), dołączanego jako prefiks do szyfrogramu,
* przygotowanie paczki ZIP,
* zaszyfrowanie części algorytmem AES-256-CBC z dopełnianiem PKCS#7,
* zaszyfrowanie klucza symetrycznego algorytmem RSAES-OAEP
(padding OAEP z funkcją MGF1 opartą na SHA-256 oraz skrótem SHA-256),
przy użyciu klucza publicznego KSeF Ministerstwa Finansów.

-- Przykład Java (biblioteka referencyjna MF):
byte[] encryptedZipPart = defaultCryptographyService.encryptBytesWithAES256(
zipParts.get(i), cipherKey, cipherIv);

6.3. Interpretacja

Sesja wsadowa stosuje identyczny mechanizm kryptograficzny co sesja interaktywna, z jedną różnicą architektoniczną: zamiast pojedynczej faktury szyfrowany jest plik ZIP zawierający wiele faktur XML. Klucz AES jest szyfrowany tym samym kluczem publicznym RSA MF. Wniosek jest tożsamy — treść faktur XML jest chroniona przed odczytem przez warstwę pośredniczącą.


7. Krok 5 — Schemat EncryptionInfo i endpoint klucza publicznego

7.1. Komenda

PowerShell
$spec = Invoke-WebRequest -Uri $specUrl | Select-Object -ExpandProperty Content | ConvertFrom-Json

Write-Host "=== SCHEMAT: EncryptionInfo ==="
$spec.components.schemas.EncryptionInfo | ConvertTo-Json -Depth 10

Write-Host "`n=== ENDPOINT KLUCZA PUBLICZNEGO ==="
$spec.paths.'/security/public-key-certificates' | ConvertTo-Json -Depth 5

7.2. Wynik

Wynik
=== SCHEMAT: EncryptionInfo ===
{
"required": ["encryptedSymmetricKey", "initializationVector"],
"properties": {
"encryptedSymmetricKey": {
"description": "Klucz symetryczny o długości 32 bajtów, zaszyfrowany algorytmem RSA
(Padding: OAEP z SHA-256), zakodowany w formacie Base64.
[Klucz publiczny Ministerstwa Finansów]"
,
"format": "byte"
},
"initializationVector": {
"description": "Wektor inicjalizujący (IV) o długości 16 bajtów,
używany do szyfrowania symetrycznego, zakodowany w formacie Base64."
,
"format": "byte"
}
}
}

=== ENDPOINT KLUCZA PUBLICZNEGO ===
GET /security/public-key-certificates
-- Opis: Pobranie aktualnych certyfikatów klucza publicznego KSeF MF

7.3. Interpretacja

Schemat EncryptionInfo potwierdza, że przy otwarciu sesji klient przekazuje wyłącznie zaszyfrowany klucz AES (encryptedSymmetricKey) — nigdy sam klucz w postaci jawnej. Klucz publiczny RSA do szyfrowania tego klucza AES jest pobierany z dedykowanego, publicznego endpointu GET /security/public-key-certificates. Odwrotna operacja — odszyfrowanie klucza AES, a tym samym faktury XML — wymaga klucza prywatnego RSA, który powinien być przechowywany wyłącznie po stronie Ministerstwa Finansów.


8. Kwestia otwarta — lokalizacja klucza prywatnego RSA

Audyt dokumentacyjny potwierdza poprawność architektury kryptograficznej po stronie klienta. Istnieje jednak kwestia, której niniejszy audyt — z definicji oparty na publicznie dostępnych źródłach — nie może rozstrzygnąć:

Kwestia niezbadana

Gdzie fizycznie jest przechowywany klucz prywatny RSA Ministerstwa Finansów, który jako jedyny umożliwia odszyfrowanie klucza AES sesji, a tym samym treści faktury XML?

Audyt 1 wykazał obecność dodatkowej warstwy infrastrukturalnej zidentyfikowanej jako Microsoft Azure Application Gateway v2 — obecnej między Impervą a backendem Kestrel. Nie jest publicznie wiadome, czy odszyfrowanie RSA następuje dopiero w backendzie Kestrel (MF), czy też wcześniej — w warstwie Azure Application Gateway.

Kluczowe pytanie: czy klucz prywatny RSA MF jest przechowywany w dedykowanym HSM znajdującym się wyłącznie pod fizyczną kontrolą MF, czy też w Azure Key Vault lub innym mechanizmie dostępnym dla warstwy Azure?

Rozstrzygnięcie tej kwestii wymagałoby: (a) dokumentacji wewnętrznej MF dotyczącej zarządzania kluczami (KMS/HSM), lub (b) odpowiedzi MF na Pytanie 4 z interwencji poselskiej, które wprost pyta o dostęp podmiotów zewnętrznych do kluczy kryptograficznych.


9. Podsumowanie — mapa kryptograficzna KSeF

Na podstawie przeprowadzonych pięciu kroków audytowych można sporządzić kompletną mapę ochrony kryptograficznej w systemie KSeF 2.0:

Przepływ danych Format Szyfrowanie E2E Widoczność dla Impervy
Wysyłka faktury (sesja online) XML → AES-Base64 ✅ AES-256-CBC + RSA-OAEP ❌ Zaszyfrowany blob
Wysyłka wsadowa (ZIP) ZIP → AES ✅ AES-256-CBC + RSA-OAEP ❌ Zaszyfrowany blob
Pobieranie faktur (eksport) ZIP szyfrowany ✅ Kluczem żądającego ❌ Zaszyfrowany blob
Zapytanie o metadane JSON (jawny) ❌ Brak ✅ Pełna jawność

10. Interpretacja wyników

10.1. Co wykazał audyt

Oficjalna dokumentacja techniczna Ministerstwa Finansów — specyfikacja OpenAPI oraz instrukcje integracyjne dla sesji online i wsadowej — jednoznacznie potwierdza istnienie szyfrowania aplikacyjnego E2E dla treści faktury XML. Szyfrowanie jest:

  • Klienckie — wykonywane po stronie nadawcy, przed wysyłką danych do sieci.
  • Symetryczne dla treści — AES-256-CBC z dopełnianiem PKCS#7.
  • Asymetryczne dla klucza — klucz AES szyfrowany RSA-OAEP/SHA-256 kluczem publicznym MF.
  • Architektonicznie wymuszone — API nie przyjmuje jawnego XML; kontrakt wymaga encryptedInvoiceContent.

10.2. Co audyt wyklucza

Audyt wyklucza scenariusz, w którym treść XML faktury jest dostępna dla Impervy w postaci jawnej w standardowym modelu operacyjnym. Imperva przetwarza zaszyfrowany blob — nie może go odczytać bez klucza prywatnego RSA MF.

10.3. Asymetria ochrony — kontrast z metadanymi JSON

Kluczowe odkrycie audytu to nie samo potwierdzenie szyfrowania XML, lecz dramatyczny kontrast z metadanymi JSON:

  • Treść faktury XML — chroniona silnym szyfrowaniem E2E. Imperva nie może jej odczytać.
  • Metadane JSON — NIP-y, kwoty, nazwy firm, daty — bez żadnej ochrony aplikacyjnej. Imperva ma do nich pełny dostęp.

MF zaprojektowało ochronę treści prawnej faktury (XML), jednocześnie nie chroniąc danych biznesowych o wysokiej wartości wywiadowczej (metadanych JSON). Z perspektywy wywiadu gospodarczego metadane mogą być wartościowsze niż sama treść dokumentu — umożliwiają masową analizę przepływów finansowych między podmiotami bez konieczności odczytywania treści faktur.


11. Wnioski końcowe

Nr Pytanie Odpowiedź audytu
P1 Terminacja TLS u WAF Impervy ✅ Potwierdzona — rekonesans sieciowy (CNAME, X-CDN, bloki IP, aktywna filtracja)
P2a Szyfrowanie E2E treści XML ✅ Potwierdzone — AES-256-CBC po stronie klienta, klucz RSA-OAEP do MF. XML nieczytelny dla Impervy.
P2b Lokalizacja klucza prywatnego RSA MF ⚠️ Niezbadana — publiczne źródła nie ujawniają, czy klucz jest w HSM pod kontrolą MF czy w infrastrukturze Azure.
P3 Jawność metadanych JSON na WAF ✅ Potwierdzona — NIP-y, kwoty, nazwy firm, daty przepływają przez Impervę w postaci jawnej.

11.1. Rekomendacja dla posłów — uzupełniające pytanie do MF

Na podstawie wyników audytu rekomendowane jest uzupełnienie interwencji poselskiej o następujące pytanie precyzujące:

Rekomendowane pytanie uzupełniające

Gdzie fizycznie jest przechowywany klucz prywatny RSA służący do odszyfrowania klucza symetrycznego AES w sesji KSeF? Czy klucz ten jest przechowywany wyłącznie w sprzętowym module HSM znajdującym się pod bezpośrednią, fizyczną kontrolą Ministerstwa Finansów, czy też w usłudze Azure Key Vault lub innym mechanizmie dostępnym dla warstwy Microsoft Azure Application Gateway ujawnionej przez audyt infrastrukturalny?

Odpowiedź na to pytanie rozstrzyga, czy szyfrowanie E2E treści faktury XML jest faktycznie skuteczne wobec podmiotów trzecich kontrolujących infrastrukturę Azure.

11.2. Ocena odpowiedzi Ministerstwa Finansów na interwencję poselską

MF odpowiedziało, że „detale operacyjne, informacje dotyczące architektury systemu oraz szczegóły współpracy z dostawcami pozostają objęte ograniczeniami informacyjnymi ze względów bezpieczeństwa". W świetle niniejszego audytu ocena tej odpowiedzi jest następująca:

  • Odpowiedź MF jest technicznie zbędna dla Pytania 2 — architektura kryptograficzna jest opisana w publicznie dostępnej dokumentacji MF na GitHub. MF odmówiło odpowiedzi na pytanie, na które odpowiedź jest jawna.
  • Odmowa ujawnienia lokalizacji klucza prywatnego RSA (Pytanie 4) jest uzasadniona ze względów bezpieczeństwa, jednak rodzi ona uzasadnione wątpliwości co do rzeczywistej suwerenności infrastrukturalnej MF.
  • Odpowiedź MF całkowicie pomija kwestię metadanych JSON (Pytanie 3), dla których nie istnieje żadna techniczna bariera ochrony przed odczytem przez Impervę.
Data:
Kategoria: Gospodarka
Tagi: #gps65 #KSeF

Grzegorz Świderski

Pupilla Libertatis - https://www.mpolska24.pl/blog/gps111

Sarmatolibertarianin, bloger, żeglarz, informatyk, trajkkarz, futurysta AI. Myślę, polemizuję, argumentuję, dyskutuję, filozofuję, politykuję, uzasadniam, prowokuję.

Komentarze 0 skomentuj »
Musisz być zalogowany, aby publikować komentarze.
Dziękujemy za wizytę.

Cieszymy się, że odwiedziłeś naszą stronę. Polub nas na Facebooku lub obserwuj na Twitterze.