Skip to content

Dokumentacja: IV nie jest prefiksem szyfrogramu — sesja-interaktywna.md:11 i sesja-wsadowa.md:20 przeczą oficjalnym klientom #839

Description

@sowamateusz

Problem

Dokumentacja sesji opisuje wektor inicjujący jako prefiks doklejany do szyfrogramu:

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,

Występuje to w dwóch miejscach:

Oba oficjalne klienty robią coś innego: wysyłają sam szyfrogram, a IV przekazują wyłącznie w polu encryption.initializationVector przy otwarciu sesji.

Dowód z oficjalnych klientów

C#CryptographyService.cs:149-162. Zwracane jest wyłącznie wyjście CryptoStream; iv trafia tylko do aes.IV:

public byte[] EncryptBytesWithAES256(byte[] content, byte[] key, byte[] iv)
{
    using Aes aes = CreateConfiguredAes(key, iv);
    using ICryptoTransform encryptor = aes.CreateEncryptor();
    ...
    return BinaryData.FromStream(output).ToArray();
}

JavaDefaultCryptographyService.java:237-248:

public byte[] encryptBytesWithAES256(byte[] content, byte[] key, byte[] iv) throws SystemKSeFSDKException {
    ...
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
    return cipher.doFinal(content);
}

W żadnym z repozytoriów nie ma konkatenacji ani obcinania 16 bajtów — ani w kodzie klienta, ani w testach E2E uruchamianych wobec środowiska TEST. Kierunek odszyfrowania jest symetryczny: pobrane części paczki eksportowej są deszyfrowane od bajtu 0, bez zdejmowania prefiksu.

Potwierdzenie pośrednie: faktury/weryfikacja-faktury.md opisuje to samo szyfrowanie bez wzmianki o prefiksie („AES-256-CBC (klucz symetryczny 256 bit, IV 128 bit, z dopełnieniem (padding) PKCS#7)"), a opis EncryptionInfo.initializationVector w OpenAPI mówi wyłącznie o wektorze używanym do szyfrowania symetrycznego, nie o elemencie ładunku.

Dlaczego to jest kosztowne

Objaw nie wskazuje na przyczynę. Po doklejeniu IV system deszyfruje 16 bajtów za dużo, więc odtworzony dokument jest dłuższy od zadeklarowanego invoiceSize i wraca status 430 z komunikatem o rozmiarze faktury:

"status": {
  "code": 430,
  "description": "Błąd weryfikacji pliku faktury",
  "details": ["Rozmiar faktury nie zgadza się z zadeklarowaną wartością: '1798'."]
}

Integrator sprawdza wtedy liczenie bajtów, BOM i kodowanie — czyli wszystko poza szyfrowaniem — podczas gdy błąd wynika z zastosowania się do zdania z dokumentacji.

Że to realny koszt, a nie hipoteza, widać w #234: zgłaszający przez dłuższy czas weryfikował rozmiar pliku „różnymi sposobami", po czym sam rozpoznał przyczynę — „niepotrzebnie doklejałem IV do zaszyfrowanej treści i tak zliczałem rozmiar całości". Zgłoszenie zamknięto jako rozwiązane, ale źródło pomyłki pozostało w dokumentacji, więc kolejni integratorzy trafiają w to samo. Sąsiadują z tym zgłoszenia o statusie 435 (#433, #677) i o rozmiarze części pakietu (#156, #215), które mają ten sam kształt objawu.

Proponowana zmiana

Usunięcie frazy „dołączanego jako prefiks do szyfrogramu" z obu plików i doprecyzowanie, że IV jest przekazywany jednorazowo w encryption.initializationVector przy otwarciu sesji (oraz przy żądaniu eksportu) i obowiązuje dla wszystkich szyfrogramów w tej sesji — co jest zresztą zachowaniem opisanym w #355.

Jeśli jednak API faktycznie akceptuje obie postacie, a zdanie jest celowe, to również warto to doprecyzować — obecnie dokumentacja i oficjalne klienty mówią wprost dwie różne rzeczy.

Chętnie przygotuję PR z poprawką, jeśli taka forma zgłoszenia jest dla Państwa wygodniejsza.


Rozbieżność wyszła przy weryfikacji materiałów dla skilla dla agentów AI do integracji KSeF w Next.js (projekt własny) — skill powielał zdanie z dokumentacji i przez to generował kod, który nie był w stanie wysłać żadnej faktury.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions