2015-07-02 46 views
6

Istnieją trzy certyfikaty w moim przykładzie załóżmy, tworzą łańcuch, ale nie wiem jeszcze, który z nich podpisano:Jak wiedzieć, które X509 certyfikat podpisany kolejny certyfikat (Java)

X509Certificate c1 = .... 
X509Certificate c2 = .... 
X509Certificate c2 = .... 

bym chciałbym wiedzieć, który certyfikat jest odpowiedzialny za podpisanie drugiego certyfikatu.

Planowano uzyskać "AuthorityKeyIdentifier" i dopasować go do "SubjectKeyIdentifier".

import org.bouncycastle.asn1. DEROctetString; 

private static String decodeKey(byte[] e) { 
    DEROctetString octet = new DEROctetString(e); 
    return octet.toString(); 
} 

String subjectKeyId = decodeKey(c.getExtensionValue("2.5.29.14")); 
String authorityKeyId = decodeKey(c.getExtensionValue("2.5.29.35")); 

Im uzyskanie następujących informacji dotyczących certyfikatów (w kolejności łańcucha): Temat/organ klucz ID pary

Wartości SubjectKeyIdentifier i AuthorityKeyIdentifier po zdekodowaniu:

certyfikatu 1: (koniec łańcucha)

#0416041482b7384a93aa9b10ef80bbd954e2f10ffb809cde 
#04183016801482b7384a93aa9b10ef80bbd954e2f10ffb809cde 

certyfikatu 2: certyfikat podpisany przez 1

#04160414ab8059c365836d1d7d13bd19c3ec1a8f0d476aa3 
#04183016801482b7384a93aa9b10ef80bbd954e2f10ffb809cde 

Certyfikat 3: Podpisany przez Certyfikat 2

(no SubjectKeyIdentifier - null bytes) 
#041830168014ab8059c365836d1d7d13bd19c3ec1a8f0d476aa3 

sformatowany i wyrównany do łatwego czytania (to samo, co jeden na górze)

------------------------------------------------------------------------------ 
     01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
------------------------------------------------------------------------------ 
Certificate 1 
#04 16 04 14  82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de 
#04 18 30 16 80 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de 

Certificate 2 
#04 16 04 14  ab 80 59 c3 65 83 6d 1d 7d 13 bd 19 c3 ec 1a 8f 0d 47 6a a3 
#04 18 30 16 80 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de 

Certificate 3 
=== == == == == == == == == == == NO DATA == == == == == == == == == == == == 
#04 18 30 16 80 14 ab 80 59 c3 65 83 6d 1d 7d 13 bd 19 c3 ec 1a 8f 0d 47 6a a3 

Spodziewałem C3 za AuthorityKeyIdentifier za równoważne c2's SubjectKeyIdentifier. wydaje się, że tak nie jest w tym przypadku.

EDYCJA: niektóre części wyniku wydają się pasować, mam pewien pomysł na "SubjectKeyIdentifier" - zawsze zaczyna się od "# 04", po którym następuje długość zawartości (w hex). Mam teraz pewien pomysł na sposób dekodowania "SubjectKeyIdentifier", ale "AuthorityKeyIdentifier" jest dla mnie wciąż wielką tajemnicą.

istotne SO post

zrobiłem nic złego z dekodowaniem? Dlaczego identyfikator AuthorityKeyIdentifier nie pasuje poprawnie do obiektu SubjectKeyIdentifier certyfikatu, który go podpisał?

+0

Czy możesz sam opublikować certyfikaty, abyśmy mogli je przeanalizować? – frasertweedale

Odpowiedz

4

Jeśli przyjrzeć się definicji ASN.1 narciarskich i AKI w RFC5280 (zgodnie z linków w swoim pytaniu) różnica staje się oczywista:

SubjectKeyIdentifier ::= KeyIdentifier 

AuthorityKeyIdentifier ::= SEQUENCE { 
    keyIdentifier    [0] KeyIdentifier   OPTIONAL, 
    authorityCertIssuer  [1] GeneralNames   OPTIONAL, 
    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } 

KeyIdentifier ::= OCTET STRING 

Tak, AKI nie jest STRING OCTET , ale SEKWENCJA trzech opcjonalnych elementów. Jednym z tych elementów jest łańcuch oktetów, który można porównać do SKI.

Numer Distinguished Encoding Rules (DER) określa reprezentację bajtów tych struktur ASN.1. Poszczególne bajty przedłużenie AKI mają następujące znaczenie (patrz A Layman's Guide to a Subset of ASN.1, BER, and DER):

04 18 30 16 80 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de 

04 OCTET STRING 
18 LENGTH 
30 SEQUENCE 
16 LENGTH 
80 CONTEXT-SPECIFIC PRIMITIVE TAG 0 
14 LENGTH 
.. DATA 

Pierwsze dwa bajty (04 18) są częścią struktury Extension (jak wyjaśniono w odnośnym pytaniu Why doesn't my key identifier match?), rzeczywisty AKI Treść rozszerzenia zaczyna się od "30 16".

Twój kod Java do dekodowania AKI powinien wyglądać następująco (z dmuchanym zamkiem):

byte[] extensionValue = cert.getExtensionValue("2.5.29.35"); 
byte[] octets = DEROctetString.getInstance(extensionValue).getOctets(); 
AuthorityKeyIdentifier authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(octets); 
byte[] keyIdentifier = authorityKeyIdentifier.getKeyIdentifier(); 
String keyIdentifierHex = new String(Hex.encode(keyIdentifier)); 

I do dekodowania narciarskich:

extensionValue = cert.getExtensionValue("2.5.29.14"); 
octets = DEROctetString.getInstance(extensionValue).getOctets(); 
SubjectKeyIdentifier subjectKeyIdentifier = SubjectKeyIdentifier.getInstance(octets); 
keyIdentifier = subjectKeyIdentifier.getKeyIdentifier(); 
keyIdentifierHex = new String(Hex.encode(keyIdentifier)); 

Również oba rozszerzenia są opcjonalne. Jeśli twój kod powinien działać z arbitralnymi certyfikatami, konieczny jest mechanizm rezerwowy (np. Weryfikacja podpisów).

+0

dziękuję za bardzo szczegółową odpowiedź. kolega z drużyny odkrył to wczoraj, to jest dokładnie wyjaśnienie, które otrzymałem. akceptowane jako odpowiedź. Nadal jestem nowy przy użyciu modułów kryptograficznych/bezpieczeństwa java i teraz zaczyna to mieć sens. – CobraEnergyDrink

+0

Nie tylko jako zabezpieczenie, należy zawsze sprawdzić child.Issuer równa się parent.Subject; to działa z powrotem do wersji 1 bez żadnych rozszerzeń. AKI/SKI *, jeśli jest obecne *, powinno być dodatkowym sprawdzeniem i może pomóc w przypadku, gdy jeden urząd certyfikacji ma więcej niż jeden certyfikat (chociaż często jest to wielokrotny certyfikat dla jednego klucza, a nie dla wielu kluczy). –

0

Jeśli szukasz naprawdę szybkiego czeku, po prostu otwórz certyfikat w oknach i poszukaj zakładki "Ścieżka certyfikacji". Umożliwia także łatwe przechodzenie w górę łańcucha certyfikatów, jeśli ma to zastosowanie. (Dodałbym zdjęcie, ale najwyraźniej nie mam jeszcze wystarczającej reputacji.)

+0

Przepraszam, ale potrzebowałem czegoś w kodzie. – CobraEnergyDrink