Programmering

Konstruer sikre netværksapplikationer med certifikater, del 2

For at opbygge sikre applikationer skal du lære værktøjene til branchen. For at hjælpe dig med at gøre dig bekendt med disse begreber introducerede jeg dig til public-key kryptografi i del 1 og forklarede, hvordan det undgår de nøgleudvekslingsproblemer, der ledsager hemmelig nøglekryptografi. Jeg undersøgte også forholdet mellem tillid og skalerbarheden af ​​kryptografi med offentlig nøgle og forklarede, hvordan certifikater og en offentlig nøgleinfrastruktur (PKI) muliggør tillid i bredere skala end kryptering med offentlig nøgle alene kan opnå. Endelig beskrev jeg certifikater og certifikatkæder og forklarede, hvordan de vedrører CA'er (certifikatmyndigheder).

Mange forskellige varianter af certifikater er tilgængelige, herunder SDSI (enkel distribueret sikkerhedsinfrastruktur), PGP (temmelig godt privatliv) og X.509. For at udvide dit sikkerhedsordforråd yderligere denne måned, vil jeg beskrive det certifikatformat, der fører pakken, og som er en nøglekomponent i de nye PKI-standarder: X.509-certifikatet.

Du kan læse hele serien om certifikater:

  • Del 1: Certifikater tilføjer værdi til kryptografi med offentlig nøgle
  • Del 2: Lær at bruge X.509-certifikaterne
  • Del 3: Brug Java CRL og X509CRL klasser
  • Del 4: Godkend klienter og servere og verificer certifikatkæder

X.509-formatet i detaljer

Den Internationale Telekommunikationsunion (ITU) udviklede og offentliggjorde X.509-certifikatformatet, som blev valgt af Public Key Infrastructure X.509 (PKIX) arbejdsgruppe i Internet Engineering Task Force (IETF). Hvis akronymer angiver styrke, har X.509 tydeligt stærke allierede.

Ved hjælp af en notation kaldet ASN.1 (Abstract Syntax Notation One) definerer X.509-standarden et certifikats format. ASN.1 er et standardiseret sprog, der beskriver abstrakte datatyper på en platformuafhængig måde.

Dokumentet "Internet X.509 Public Key Infrastructure - Certificate and CRL Profile" (se Ressourcer for et link), der er offentliggjort af PKIX-arbejdsgruppen, beskriver et X.509-certifikatformat i form af ASN.1-notation. Det er en fascinerende læsning, hvis du er interesseret i den slags ting.

En datatype - såsom et certifikat - defineret i ASN.1 er ikke nyttig, før den utvetydigt kan definere, hvordan man repræsenterer en forekomst af en datatype som en række bits. For at give datatypen den funktionalitet bruger ASN.1 Distinguished Encoding Rules (DER), der definerer, hvordan man entydigt koder ethvert ASN.1-objekt.

Med en kopi af et X.509-certifikats ASN.1-definition og en viden om DER kan du skrive et Java-program, der læser og skriver X.509-certifikater og interopererer med lignende applikationer skrevet på andre programmeringssprog. Heldigvis bliver du sandsynligvis aldrig nødt til at gøre så meget besvær, fordi Java 2 Platform, Standard Edition (J2SE) leveres med indbygget support til X.509-certifikater.

X.509 for (næsten) ingenting

Alle certifikatrelaterede klasser og grænseflader findes i pakken java.security.cert. Ligesom de andre medlemmer af Suns familie af sikkerheds-API'er blev certifikatpakken designet omkring fabriksparadigmet, hvor en eller flere Java-klasser definerer en generisk grænseflade til en pakkes tilsigtede funktionalitet. Klasserne er abstrakte, så applikationer kan ikke instantiere dem direkte. I stedet opretter og returnerer en fabriksklasse-instans forekomster af de abstrakte klassers særlige undertyper. Fabriksparadigmet omgår Java's stærke typografi, men til gengæld tillader koden at køre uden rekompilering i en bredere vifte af miljøer.

Det java.security.cert.Certificate og java.security.cert.CRL abstrakte klasser definerer grænsefladen. De repræsenterer henholdsvis certifikater og certifikat tilbagekaldelseslister (CRL'er). Det CertificateFactory klasse er deres fabrik.

Det java.security.cert pakken indeholder konkrete implementeringer af Certifikat og CRL abstrakte klasser: X509 Certifikat og X509CRL klasser. Disse to klasser implementerer grundlæggende certifikat og CRL-funktionalitet, og udvider det derefter med X.509-specifik funktionalitet. Når en CertificateFactory instans returnerer en forekomst af begge klasser, et program kan enten bruge det som det er eller eksplicit kaste det til X.509-formularen.

I java.security.cert pakke, interface X509 Udvidelse definerer en grænseflade til et X.509-certifikats udvidelser. Udvidelser er valgfri komponenter, der giver en mekanisme for certifikatskabere til at knytte yderligere oplysninger til et certifikat. For eksempel kan et certifikat bruge KeyUsage udvidelse for at indikere, at den kan bruges til kodesignering.

Det java.security.cert pakken indeholder også en SPI-klasse (Service Provider Interface). EN kryptografisk tjenesteudbyder der ønsker at understøtte en certifikat type udvider SPI. Java 2 leveres med et SPI til X.509-certifikater.

Lad os tage et mere detaljeret kig på klasser og grænseflader i java.security.cert pakke. For kortfattethed vil jeg kun diskutere de mest nyttige metoder. For mere omfattende dækning opfordrer jeg dig til at læse Suns dokumentation. (Se ressourcer.)

java.security.cert.CertificateFactory

Historien begynder med java.security.cert.CertificateFactory. Det CertificateFactory klasse har statiske metoder, der skaber en CertificateFactory eksempel for en bestemt type certifikat og metoder, der opretter både certifikater og CRL'er fra data leveret i en inputstrøm. Jeg vil kort beskrive de vigtigste metoder og derefter forklare, hvordan man bruger disse metoder, når jeg genererer X.509-certifikater og CRL'er. Senere i artiklen præsenterer jeg kode, der demonstrerer metoderne i aktion.

  • offentlig statisk CertificateFactory getInstance (String stringType) og offentlig statisk CertificateFactory getInstance (String stringType, String stringProvider) instantiere og returnere en forekomst af en certifikatfabrik for den certifikattype, der er angivet af stringType parameter. For eksempel, hvis værdien af stringType er strengen "X.509", begge metoder returnerer en forekomst af CertificateFactory klasse egnet til at oprette forekomster af klasserne X509 Certifikat og X509CRL. Den anden metode accepterer navnet på en bestemt kryptografisk tjenesteudbyder som et argument og bruger denne udbyder i stedet for standard.
  • offentligt endeligt certifikat generere Certifikat (InputStream inputstream) instantierer og returnerer et certifikat ved hjælp af data, der er læst fra det leverede InputStream eksempel. Hvis streamen indeholder mere end et certifikat, og streamen understøtter mærke() og Nulstil() operationer, vil metoden læse et certifikat og lade strømmen være placeret inden det næste.
  • offentlig endelig samling generere certifikater (InputStream inputstream) instantierer og returnerer en certifikatsamling ved hjælp af data, der er læst fra den medfølgende InputStream eksempel. Hvis den givne stream ikke understøtter mærke() og Nulstil(), metoden vil forbruge hele strømmen.
  • offentlig endelig CRL generereCRL (InputStream inputstream) instantierer og returnerer en CRL ved hjælp af data, der er læst fra den leverede InputStream eksempel. Hvis streamen indeholder mere end en CRL og understøtter mærke() og Nulstil() operationer, vil metoden læse en CRL og lade strømmen være placeret inden den næste.
  • offentlig endelig samling generere CRL'er (InputStream inputstream) instantierer og returnerer en samling af CRL'er ved hjælp af data, der er læst fra den leverede InputStream eksempel. Hvis den givne stream ikke understøtter mærke() og Nulstil(), offentlig endelig samling generereCRL'er (InputStream inputstream) vil forbruge hele strømmen.

Det er vigtigt at forstå, hvordan disse fire metoder opfører sig, når de genererer X.509-forekomster fra en datastrøm. Lad os se.

Det generereCertifikat () og generere CRL () metoder forventer, at inputstrømens indhold skal indeholde henholdsvis DER-kodede repræsentationer af et certifikat eller en CRL.

Både generere Certifikater () og generereCRL'er () metoder forventer, at indholdet af inputstrømmen indeholder enten en sekvens af DER-kodede repræsentationer eller et PKCS # 7 (Public-Key Cryptography Standard # 7) -certifikat eller CRL-sæt. (Se ressourcer for links.)

java.security.cert.Certificate

java.security.cert.Certificate definerer grænsefladen, der er fælles for alle typer certifikater: X.509, PGP og en lille håndfuld andre. Denne klasses vigtigste metoder er:

  • offentlig abstrakt PublicKey getPublicKey () returnerer den offentlige nøgle relateret til certifikatforekomsten, som denne metode kaldes til.
  • offentlig abstrakt byte [] getEncoded () returnerer certifikatets kodede form.
  • offentlig abstrakt ugyldig bekræftelse (PublicKey publickey) og offentlig abstrakt ugyldig verificering (PublicKey publickey, String stringProvider) kontrollere, at den private nøgle, der svarer til den leverede offentlige nøgle, underskrev det pågældende certifikat. Hvis tasterne ikke stemmer overens, kaster begge metoder a Underskrift undtagelse.

java.security.cert.X509Certificate

Klassen java.security.cert.X509Certificate udvider Certifikat klasse beskrevet ovenfor og tilføjer X.509-specifik funktionalitet. Denne klasse er vigtig, fordi du normalt interagerer med certifikater på dette niveau, ikke som basisklassen.

  • offentlig abstrakt byte [] getEncoded () returnerer den kodede form for dette certifikat som ovenfor. Metoden bruger DER-kodning til certifikatet.

Mest af java.security.cert.X509CertificateDen ekstra funktionalitet består af forespørgselsmetoder, der returnerer oplysninger om certifikatet. Jeg præsenterede det meste af denne information i del 1. Her er metoderne:

  • offentlig abstrakt int getVersion () returnerer certifikatets version.
  • offentlig abstrakt Principal getSubjectDN () returnerer oplysninger, der identificerer certifikatets emne.
  • offentlig abstrakt Principal getIssuerDN () returnerer oplysninger, der identificerer certifikatets udsteder, som typisk er CA, men som kan være genstand, hvis certifikatet er selvsigneret.
  • offentlig abstrakt Dato getNotBefore () og offentlig abstrakt Dato getNotAfter () returnerer værdier, der begrænser den periode, hvor udstederen er villig til at garantere for emnets offentlige nøgle.
  • offentlig abstrakt BigInteger getSerialNumber () returnerer certifikatets serienummer. Kombinationen af ​​certifikatets udstedernavn og serienummer er dens unikke identifikation. Denne kendsgerning er afgørende for tilbagekaldelse af certifikater, som jeg vil diskutere mere detaljeret i næste måned.
  • offentlig abstrakt streng getSigAlgName () og offentlig abstrakt streng getSigAlgOID () returnere oplysninger om algoritmen, der bruges til at underskrive certifikatet.

Følgende metoder returnerer oplysninger om de udvidelser, der er defineret for certifikatet. Husk, udvidelser er mekanismer til at knytte information til et certifikat; de vises kun på version 3-certifikater.

  • offentlig abstrakt int getBasicConstraints () returnerer længden af ​​et certifikats begrænsningssti fra Grundlæggende begrænsninger udvidelse, hvis defineret. Begrænsningsstien angiver det maksimale antal CA-certifikater, der kan følge dette certifikat i en certificeringssti.
  • offentlig abstrakt boolsk [] getKeyUsage () returnerer formålet med certifikatet som kodet i KeyUsage udvidelse.
  • public Set getCriticalExtensionOIDs () og public Set getNonCriticalExtensionOIDs () returnere en samling af objekt-id'er (OID'er) for udvidelser markeret henholdsvis kritiske og ikke-kritiske. En OID er en række heltal, der universelt identificerer en ressource.

Jeg vil ikke efterlade dig uden kode at lege med, så i stedet for at gå ned i CRL'er, hvilket er et komplet emne alene, præsenterer jeg koden og efterlader CRL'er til del 3.

Koden

Følgende klasse demonstrerer, hvordan man opnår en certifikatfabrik, hvordan man bruger fabrikken til at generere et certifikat fra den DER-kodede repræsentation i en fil, og hvordan man udtrækker og viser oplysninger om certifikatet. Du bemærker, hvor lidt du skal bekymre dig om den underliggende kodning.