Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

HTTPS v Jave

K práci s protokolom HTTPS (Hypertext Transfer Protocol Secure) možno podobne ako v prípade HTTP použiť triedy z balíka java.net. Ak potrebujeme napríklad z nejakého servera stiahnuť webovú stránku cez HTTPS, stačí vytvoriť objekt java.net.URL s požadovanou adresou, otvoriť spojenie az príslušného objektu InputStream prečítať dáta.

String address = "https://www.google.com";
URL url = new URL(address);
URLConnection connection = url.openConnection();
InputStream in = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
    in = connection.getInputStream();
    byte[] buffer = new byte[8192];
    int size;
    while ((size = in.read(buffer)) != -1) {
        out.write(buffer, 0, size);
    }
} finally {
    if (in != null) {
        in.close();
    }
}
String content = out.toString("UTF-8");

Kód vyššie funguje za predpokladu, že je HTTPS server resp. jeho certifikát považovaný za dôveryhodný. Ak nie je tomu tak, spojenie zlyhá a dôjde k vyhodenie výnimky javax.net.ssl.SSLHandshakeException.

javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

V tomto článku si ukážeme, ako funguje overovania serverových SSL / TLS certifikátov a kde sú uložené certifikáty dôveryhodných autorít.

Certifikačná cesta

Aby bol certifikát servera považovaný za dôveryhodný, musí byť vydaný dôveryhodnou certifikačnou autoritou. Certifikát certifikačnej autority vydáva buď certifikačná autorita sama, v tomto prípade sa jedná o koreňovú certifikačnú autoritu, alebo jej nadradená certifikačná autorita.

Certifikáty tvoria tzv. Reťazec (chain) resp. certifikačný cestu (certification path), kde na jednom konci stojí certifikát koreňovej certifikačnej autority, na druhom konci certifikát servera a medzi nimi sa nachádza ľubovoľný počet certifikátov podriadených certifikačných autorít.

Truststore

Certifikáty dôveryhodných certifikačných autorít sú v Jave uložené v úložisku dôveryhodných certifikátov, v tzv. Truststore.

Východiskovým úložiskom dôveryhodných certifikátov je súbor cacerts v adresári C:\Program Files\Java\jre7\lib\security. Umiestnenie adresára sa môže líšiť podľa verzie JRE. Certifikáty sú uložené vo formáte JKS (Java KeyStore) a chránené heslom. Predvolené heslo znie changeit.

Úložisko je možné spravovať pomocou nástroja keytool, ktorý je súčasťou Java SE Development Kit. Napríklad obsah možno vypísať príkazom:

keytool -list -storepass changeit -keystore "C:\Program Files\Java\jre7\lib\security\cacerts"

Popis všetkých parametrov nástroje keytool je k dispozícii na stránkach Oracle

Umiestnenie úložiska dôveryhodných certifikátov možno pre daný proces zmeniť pomocou argumentu JVM javax.net.ssl.trustStore. Argumentom javax.net.ssl.trustStorePassword možno špecifikovať heslo.

Príklad: Spustenie aplikácie s vlastným úložiskom dôveryhodných certifikátov:

java -Djavax.net.ssl.trustStore=mujtruststore.jks -Djavax.net.ssl.trustStorePassword=supertajneheslo -jar moje-aplikace.jar

Trust manager

Niekedy je potrebné mať nad overovaním SSL / TLS certifikátov väčšiu kontrolu. Predstavme si napríklad, že naše aplikácie komunikuje s aplikáciami našich obchodných partnerov. Každý partner má vlastný server s vlastným SSL certifikátom.

Naše aplikácie potrebuje overiť, že certifikát servera prislúcha danému partnerovi. Ďalším príkladom je situácia, keď nechceme vôbec používať file system, ale certifikáty spravujeme v rámci našej aplikácie, uložené napr. V databáze. Alebo si predstavme prípad, kedy certifikáty nechceme overovať vôbec.

Pre všetky tieto prípady môžeme použiť vlastnú implementáciu rozhrania javax.net.ssl.X509TrustManager. Overenie certifikátov servera sa deje v metódou checkServerTrusted. Metóda vyhadzuje výnimku CertificateException, ak overenie zlyhá a certifikát nie je považovaný za dôveryhodný.

Príklad: Náš vlastný trust manager, ktorý akceptuje ľubovoľný certifikát servera.

public class MyTrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        throw new CertificateException();
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        /* Ověřit řetězec certifikátů */
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }

}

Nasledujúci kód pre dané HTTPS spojenie nastaví náš trust manager. Trust manager je ukrytý v objekte triedy SSLSocketFactory, ktorý najprv vytvoríme pomocou triedy SSLContext. Objekt SSLSocketFactory nastavíme pre dané pripojenie metódou setSSLSocketFactory rozhranie HttpsURLConnection.

MyTrustManager trustManager = new MyTrustManager();
TrustManager[] tm = { trustManager };
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tm, null);
SSLSocketFactory socketFactory = context.getSocketFactory();

String address = "https://localhost";
URL url = new URL(address);
URLConnection connection = url.openConnection();
if (connection instanceof HttpsURLConnection) {
    ((HttpsURLConnection) connection).setSSLSocketFactory(socketFactory);
}

Alternatívne je možné pomocou metódy SSLContext.setDefault nastaviť SSL kontext s vlastným trust managerom globálne pre celú aplikáciu.

Zhrnutie

Čo teda robiť, ak v našej aplikácii dochádza k SSLHandshakeException pri pokuse o pripojenie na server cez HTTPS?

Možnosti máme tieto:

  1. Pridať certifikát servera resp. certifikát certifikačnej autority do východzieho úložiska dôveryhodných certifikátov do súboru cacerts.
  2. Uložiť certifikát do vlastného úložiska a spustiť aplikáciu s argumentmi JVM javax.net.ssl.trustStore a javax.net.ssl.trustStorePassword.
  3. Použiť vlastnú implementáciu X509TrustManager.

 

Všetky články v sekcii
Java - Pre pokročilých
Článok pre vás napísal Silvinios
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity