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
.
|
|
|