Podstawy weryfikacji podpisów XML

Adobe AIR 1.5 i starsze wersje

Skrócone omówienia i przykłady kodu ilustrujące sprawdzanie podpisów XML można znaleźć w następujących artykułach z serii Quick Start w witrynie Adobe Developer Connection:

Środowisko Adobe® AIR® udostępnia klasę XMLSignatureValidator oraz interfejs IURIDereferencer służące do weryfikowania podpisów XML. Składnia XML dopuszczalna w klasie XMLSignatureValidator jest podzbiorem zaleceń W3C dotyczących składni i przetwarzania podpisów XML. (Ponieważ obsługiwany jest tylko podzbiór zaleceń, nie wszystkie formalnie poprawne podpisy mogą być zweryfikowane). Środowisko AIR nie udostępnia interfejsu API do tworzenia podpisów XML.

Klasy służące do weryfikacji podpisów XML

Interfejs API weryfikacji podpisów XML obejmuje następujące klasy:

Pakiet

Klasy

flash.security

Stałe ciągi znaków XMLSignatureValidator zdefiniowane są w następujących klasach:

flash.events

Korzystanie z klas do weryfikacji podpisów XML

Aby skorzystać z klasy XMLSignatureValidator do weryfikacji podpisu XML, należy:

  • Utworzyć obiekt XMLSignatureValidator.

  • Udostępnić implementację interfejsu IURIDereferencer. Obiekt XMLSignatureValidator wywołuje metodę dereference() obiektu IURIDereferencer, przekazując identyfikator URI dla każdego z odwołań w podpisie. Metoda dereference() musi przetłumaczyć identyfikator URI i zwrócić dane będące celem odwołania (może to być sam dokument podpisu lub zasób zewnętrzny).

  • Określić ustawienia zaufania, sprawdzania ważności i weryfikacji odwołań w obiekcie XMLSignatureValidator w sposób odpowiedni do danego zastosowania.

  • Dodać detektory zdarzeń complete oraz error .

  • Wywołać metodę verify() , przekazując podpis przeznaczony do weryfikacji.

  • Obsłużyć zdarzenia complete i error oraz zinterpretować wyniki.

W poniższym przykładzie zaimplementowano funkcję validate() , które weryfikuje ważność podpisu XML. Właściwości klasy XMLSignatureValidator są ustawiane w taki sposób, że certyfikat użyty do podpisywania musi znajdować się w systemowym magazynie certyfikatów zaufanych lub prowadzić poprzez łańcuch do certyfikatu w magazynie certyfikatów zaufanych. W przykładzie przyjęto ponadto założenie, że istnieje odpowiednia klasa IURIDereferencer o nazwie XMLDereferencer .

private function validate( xmlSignature:XML ):void 
{ 
    var verifier:XMLSignatureValidator = new XMLSignatureValidator(); 
    verifier.addEventListener(Event.COMPLETE, verificationComplete); 
    verifier.addEventListener(ErrorEvent.ERROR, verificationError); 
    try 
    { 
        verifier.uriDereferencer = new XMLDereferencer(); 
 
        verifier.referencesValidationSetting = 
            ReferencesValidationSetting.VALID_IDENTITY; 
        verifier.revocationCheckSetting = RevocationCheckSettings.BEST_EFFORT; 
        verifier.useSystemTrustStore = true; 
         
        //Verify the signature 
        verifier.verify( xmlSignature ); 
    } 
    catch (e:Error) 
        { 
            trace("Verification error.\n" + e); 
        } 
} 
 
//Trace verification results 
private function verificationComplete(event:Event):void 
 
    var signature:XMLSignatureValidator = event.target as XMLSignatureValidator; 
    trace("Signature status: " + signature.validityStatus + "\n"); 
    trace("  Digest status: " + signature.digestStatus + "\n"); 
    trace("  Identity status: " + signature.identityStatus + "\n"); 
    trace("  Reference status: " + signature.referencesStatus + "\n"); 
} 
 
private function verificationError(event:ErrorEvent):void 
{ 
    trace("Verification error.\n" + event.text);                 
}

Proces weryfikacji podpisu XML

Po wywołaniu metody XMLSignatureValidator verify() środowisko AIR wykonuje następujące czynności:

  • Środowisko wykonawcze weryfikuje integralność kryptograficzną podpisu, korzystając z klucza publicznego certyfikatu użytego do podpisywania.

  • Środowisko wykonawcze określa integralność kryptograficzną, tożsamość i wiarygodność certyfikatu na podstawie bieżących ustawień obiektu XMLSignatureValidator.

    Zaufanie pokładane w certyfikacie użytym do podpisywania jest kluczem do wiarygodności całego procesu weryfikacji. Weryfikacja podpisu odbywa się przy wykorzystaniu ściśle zdefiniowanego procesu kryptograficznego, ale wiarygodność certyfikatu użytego do podpisywania jest czynnikiem, którego nie da się określić algorytmicznie.

    W ogólnym ujęciu istnieją trzy sposoby określenia wiarygodności certyfikatu:

    • W oparciu o ośrodki certyfikacji i magazyn certyfikatów zaufanych systemu operacyjnego.

    • Uzyskanie bezpośrednio od osoby podpisującej kopii certyfikatu, innego certyfikatu będącego „kotwicą zaufania” dla danego certyfikatu albo informacji (np. klucza publicznego) wystarczających do niezawodnego zidentyfikowania certyfikatu.

    • Zapytanie użytkownika aplikacji, czy ufa danemu certyfikatowi. Takie pytanie nie jest prawidłową formą potwierdzania zaufania w przypadku certyfikatów samopodpisanych, ponieważ zawarte w nich informacje identyfikacyjne są ze swojej natury niewiarygodne.

  • Środowisko wykonawcze weryfikuje integralność kryptograficzną podpisanych danych.

    Podpisane dane są weryfikowane z pomocą opracowanej przez programistę implementacji interfejsu IURIDereferencer. Dla każdego odwołania w dokumencie podpisu wywoływana jest metoda dereference() z implementacji IURIDereferencer. Dane zwrócone przez metodę dereference() służą następnie do obliczenia wyciągu referencyjnego. Wartość tego wyciągu jest porównywana z wyciągiem zapisanym w dokumencie podpisu. Zgodność wyciągów świadczy o tym, że dane nie zostały zmodyfikowane od chwili, kiedy je podpisano.

    Jednym z ważnych uwarunkowań, które należy brać pod uwagę przy interpretacji wyników weryfikacji podpisów XML, jest fakt, że bezpieczne są tylko treści podpisane. Weźmy na przykład pod uwagę podpisany manifest zawierający listę plików w pakiecie. Gdy obiekt XMLSignatureValidator weryfikuje podpis, potwierdza tylko brak modyfikacji samego manifestu. Dane w plikach nie są podpisane, a więc wynik weryfikacji podpisu będzie pozytywny nawet w sytuacji, gdy pliki wymienione w manifeście zostały zmienione bądź usunięte.

    Uwaga: Aby zweryfikować pliki wskazane w takim manifeście, można obliczyć wyciąg na podstawie danych z plików (korzystając z tego samego algorytmu, co w przypadku manifestu) i porównać wynik z wyciągiem przechowywanym w podpisanym manifeście. W niektórych przypadkach należy także sprawdzić, czy nie pojawiły się dodatkowe pliki.

Interpretacja wyników weryfikacji

Wyniki weryfikacji są przekazywane za pośrednictwem właściwości statusu obiektu XMLSignatureValidator. Właściwości te można odczytać po tym, jak obiekt Validator wywoła zdarzenie complete . Cztery właściwości statusu to: validityStatus , digestStatus , identityStatus oraz referencesStatus .

Właściwość validityStatus

Właściwość validityStatus informuje o ogólnej ważności podpisu. Wartość validityStatus zależy od trzech pozostałych właściwości statusu i może być równa:

  • valid — jeśli właściwości digestStatus , identityStatus i referencesStatus mają wartość valid .

  • invalid — jeśli co najmniej jedna z pozostałych właściwości statusu ma wartość invalid .

  • unknown — jeśli co najmniej jedna z pozostałych właściwości statusu ma wartość unknown i żadna z nich nie ma wartości invalid .

Właściwość digestStatus

Właściwość digestStatus informuje o wynikach weryfikacji kryptograficznej wyciągu z wiadomości. Właściwość digestStatus może mieć jedną z następujących wartości:

  • valid — jeśli dokument podpisu nie został zmodyfikowany od chwili podpisania.

  • invalid — jeśli dokument podpisu został zmodyfikowany lub ma nieprawidłową postać.

  • unknown — jeśli nie powiodło się wykonanie metody verify() .

Właściwość identityStatus

Właściwość identityStatus informuje o statusie certyfikatu użytego do podpisywania. Wartość tej właściwości zależy od kilku czynników, w tym:

  • integralności kryptograficznej certyfikatu;

  • od tego, czy upłynął termin ważności certyfikatu lub certyfikat został unieważniony;

  • od tego, czy certyfikat jest zaufany na danym komputerze;

  • od stanu obiektu XMLSignatureValidator (np. od tego, czy dodano kolejne certyfikaty do łańcucha zaufania, czy te certyfikaty są zaufane i od wartości właściwości useSystemTrustStore i revocationCheckSettings ).

Właściwość identityStatus może mieć następujące wartości:
  • valid — aby certyfikat używany do podpisywania został uznany za ważny, musi spełniać następujące warunki:

    • Certyfikat użyty do podpisywania musi być niezmodyfikowany.

    • Certyfikat użyty do podpisywania nie może być unieważniony, jego termin nie może być przekroczony, chyba że w podpisie znajduje się poprawny znacznik czasu. Jeśli podpis jest opatrzony znacznikiem czasu, certyfikat będzie uważany za ważny, o ile był ważny w chwili podpisania dokumentu. (Certyfikat użyty przez usługę dodającą znacznik czasu do podpisania znacznika musi być powiązany łańcuchem z zaufanym certyfikatem głównym na komputerze użytkownika).

    • Certyfikat użyty do podpisywania musi być zaufany. Certyfikat jest zaufany, jeśli znajduje się w systemowym magazynie certyfikatów zaufanych lub jest połączony łańcuchem z innym certyfikatem w systemowym magazynie certyfikatów zaufanych, a właściwość useSystemTrustStore jest ustawiona na true. Możliwe jest także wskazanie certyfikatu jako zaufanego przy użyciu metody addCertificate() obiektu XMLSignatureValidator.

    • Certyfikat musi być w istocie certyfikatem użytym do podpisywania.

  • invalid — upłynął termin ważności certyfikatu lub certyfikat został unieważniony, a podpis nie zawiera znacznika czasu potwierdzającego ważność w momencie podpisywania; lub certyfikat został zmodyfikowany.

  • unknown — certyfikat nie jest nieważny, ale nie jest również zaufany. Przykładowo, status unknown będzie zwracany w przypadku certyfikatów samopodpisanych (o ile nie zostaną jawnie wskazane jako zaufane). Właściwość identityStatus przyjmuje też wartość unknown , jeśli metoda verify() nie została wykonana bezbłędnie lub jeśli tożsamość nie została sprawdzona, ponieważ wyciąg podpisu jest niepoprawny.

Właściwość referencesStatus

Właściwość referencesStatus informuje o integralności kryptograficznej referencji w elemencie SignedData podpisu.

  • valid — jeśli obliczone wyciągi poszczególnych referencji w podpisie są identyczne z odpowiednimi wyciągami zapisanymi w podpisie XML. Status valid oznacza, że podpisane dane nie zostały zmodyfikowane.

  • invalid — jeśli którykolwiek z obliczonych wyciągów nie zgadza się z odpowiednim wyciągiem w podpisie.

  • unknown — jeśli wyciągi referencji nie zostały sprawdzone. Referencje nie są sprawdzane, jeśli wyciąg całego podpisu ma status invalid lub jeśli certyfikat użyty do podpisywania jest nieważny. Jeśli właściwość identityStatus ma wartość unknown , wówczas referencje są sprawdzane tylko wtedy, gdy właściwość referencesValidationSetting ma wartość validOrUnknown .