» »

[JAVA] HTTPS client

[JAVA] HTTPS client

Fizikalko ::

Torej, rad bi uporabil nek servis (na nekem URL-ju) in nanj pristopal iz moje Java aplikacije. Ta servis mi, recimo, podeli certifikat (trajno). Ima kdo kak link na tutorial (ali pa lče lahko kar kodo gor vrže) - kako narediti HTTPS java klienta?

Klient mora preko POST metode v body-ju poslati nek XML in za response prav tako dobi XML. XML imam pripravljen, znam tudi bp sparsat response, le komunikacija preko HTTPS s certifikatom me zafrkava.

Fizikalko ::

Zaenkrat vem, da moram najprej:

- kreirati novi keystore (kako?)

- importirati certifikat v ta keystore

- napisati klienta (???)

mainman ::

Za klienta uporabi httpclient od apache-commons.

Zadeva uporablja client side certifikat. Če tega ne rabiš je postopek dokaj poben.

Primer kode je tukaj:

public byte[] send(byte[] xml) {
try {
System.setProperty("javax.net.ssl.keyStore", "c:/clientcert.pfx");
System.setProperty("javax.net.ssl.keyStorePassword", "clientKeystorePassword");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.trustStore", "c:/server.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "serverKeystorePassword");
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol" );
Security.addProvider( new com.sun.net.ssl.internal.ssl.Provider() );

HttpClient client = new HttpClient();

PostMethod method = new PostMethod("https://nek.naslov/nekServis.ws");
method.setDoAuthentication(true);

method.setRequestHeader("Content-Type", "text/xml");

ByteArrayRequestEntity byteReqEnt = new ByteArrayRequestEntity(xml, "text/xml");

method.setRequestEntity(byteReqEnt);


int status = client.executeMethod(method);
System.out.println("ST "+status);


System.out.println(method.getResponseBodyAsString());


return method.getResponseBody();
} catch (Throwable t){
throw new RuntimeException(t);
}
}

Fizikalko ::

Najprej hvala za odgovor...

A mi lahko mal podrobneje razložiš tole kodo, sploh tiste setterje (za keystore itd)?

Kaj moram najprej narediti, preden tole kodo lahko uporabim?

mainman ::

Serverski certifikat moraš uvoziti v keystore.

C:\java\jre1.6.0_02\bin\keytool -import -trustcacerts -alias server -file c:\work\mvrata\server.cer -keystore c:\work\mvrata\cacerts

Fizikalko ::

OK, samo tole mi povej, kaj so te lokacije:

C:\clientcert
c:\server.keystore
C:\work\mvrata

oziroma, kje imaš v tem primeru certifikat?

Sklepam, da v mvrata\server.cer?

Kaj je potem cacerts mapa?

Zgodovina sprememb…

  • spremenilo: Fizikalko ()

mainman ::

server.cer je serverski certifikat od https strani. Dobiš ga tako, da v internet explorerju greš na https stran in ga izvoziš(ključavnica v status baru).

cacers je keystore v katerega boš uvozil serverski certifikat. Če datoteka ne obstaja ni problema, tool jo bo kreiral. Ukaz sem na hitro vzel iz enega projekta, ki sem ga delal tako da so datoteke malo drugače poimenovane. V kodi je namesto cacerts server.keystore.

c:\work\mvrata je pač nek direktorij. Lahko daš poljubnega.

clientcert.pfx je certifikat, ki si ga dobil. To je klientovski certifikat ki se uporablja za dostop do strani. Če po pravici povem to ni certifikat ampak keystore, ki vsebuje certifikat. Keystore ima poseben format in sicer pkcs12 zato je v system.setPropertie tudi dodaten ukaz, ki nastavlja format keystora.

Saj zadeva je čisto enostavna. Malo poguglaj pa boš takoj našel 1000 in en namig kako se zadeve lotiti.

Zgodovina sprememb…

  • spremenilo: mainman ()

Fizikalko ::

OK, res ti najlepša hvala, bom sprobal, pa se še oglasim...

Če ma pa kdo še kaj za predlagat, pa kar.

nicnevem ::

Mogoče bi ti prav prišel tale tutorial/recept:

Using JSSE for secure socket communication

Še izvorna koda primerov v tutorialu: jsse-source.zip
overcomingbias.com -- transhumanizem.org -- singinst.org

Fizikalko ::

OK, super, tnx.

Še nekaj: kaj pa, če potem jaz hočem na nekem URLju čakat na določen XML paket, ki naj bi mi ga nekdo poslal? Kako se pa to naredi? Zaenkrat lahko tudi brez SSL...

Fizikalko ::

Ok, zdjle se mal s temle zafrkavam...

@maiman: Kaj jet tisti -trustcacerts -alias server?

Ko izvedem sledečo komando:

keytool -import -trustcacerts -alias server -file d:\temp\cert\server.cer -keystore c:\temp\cacerts,

mi javi napako:

keystore file exsists, but is empty!

Prosim za pomoč.

Fizikalko ::

Mah, že rešil...

Fizikalko ::

mainman...

Kako si pa String xml pretvoril v byte niz?

Fizikalko ::

Ok, sem uspel nekako tole implementrat za vajo. Ko pošljem s tole send metodo, mi server javi:

java.lang.RuntimeException: java.net.SocketException: Default SSL context init failed: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded

Certifikta mam, tako server kot client, uvožen je tudi.

Koda:

public class sender {

public static byte[] send(byte[] xml) {
try {
System.setProperty("javax.net.ssl.keyStore", "D:\\temp\\cert\\certifikatOdServisa.pfx");
System.setProperty("javax.net.ssl.keyStorePassword", "mojpassword, ki sem ga dobil od servisa");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs7");
System.setProperty("javax.net.ssl.trustStore", "D:\\temp\\cert\\cacerts.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "passwordOdKeystore-a");
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol" );
Security.addProvider( new com.sun.net.ssl.internal.ssl.Provider() );

HttpClient client = new HttpClient();

PostMethod method = new PostMethod("https://naslovServisa");
method.setDoAuthentication(true);

method.setRequestHeader("Content-Type", "text/xml");

ByteArrayRequestEntity byteReqEnt = new ByteArrayRequestEntity(xml, "text/xml");

method.setRequestEntity(byteReqEnt);


int status = client.executeMethod(method);
System.out.println("ST "+status);


System.out.println(method.getResponseBodyAsString());


return method.getResponseBody();
} catch (Throwable t){
throw new RuntimeException(t);
}
}


}

Fizikalko ::

probal tud pcks12, ni haska

Fizikalko ::

mainman ali kdorkoli... a kdo ve, kaj bi blo narobe? Res hvala že vnaprej.

JureVpm ::

Če nastaviš še propery
System.setProperty("javax.net.debug", "all");
Ti bo zbruhalo ene deset strani izpisov. Videl boš na primer, katere certifikate ti je https klient naložil v tvoju trust listo, katere izdajatelje ima strežnik v svoji trust listi, s katerim certifikatom si se kot klient avtenticiral, kako se je izmenjeval chalenge, ...
Potem pa študirat SSL/TSL handshakeing ;-)

peterv6i ::

Če ti kaj pomaga...
tukaj je primer kjer se uporablja keystore in trustore (certifikati naloženi iz diska)..
To sem potreboval za povezavo z FURS-om...

package com.peterv;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyManagementException;

import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

public class KeystoreHTTPS {

    public KeystoreHTTPS() throws Exception {
        //try {

            System.out.println("Begin");
            URL url = new URL("https://blagajne-test.fu.gov.si:9002/v1/cash_registers");
            String USER_AGENT = "Mozilla/5.0";
            String truststore = "c:/cert/test-tls.cer";
            String keyStore = "C:\\cert\\10031685-1.p12";
            String keyStorePassword = "Geslo123#";
            String keyPassword = "Geslo123#";
            String KeyStoreType = "PKCS12";
            String KeyManagerAlgorithm = "SunX509";
            String SSLVersion = "TLS";
            HttpsURLConnection con = getHttpsURLConnection(url, truststore, keyStore, keyStorePassword, keyPassword, KeyStoreType, KeyManagerAlgorithm, SSLVersion);
            con.setConnectTimeout(1000); //timeout
            //add reuqest header
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
            con.setRequestProperty("Content-type", "text/xml; charset=utf-8");
            con.setRequestProperty("SOAPAction", "\"/echo\"");

            String xml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:fu=\"http://www.fu.gov.si/\">\n"
                    + "   <soapenv:Header/>\n"
                    + "   <soapenv:Body>\n"
                    + "      <fu:EchoRequest>130031{$1}</fu:EchoRequest>\n"
                    + "   </soapenv:Body>\n"
                    + "</soapenv:Envelope>";

            con.setDoOutput(true);

            OutputStream reqStream = con.getOutputStream();

            reqStream.write(xml.getBytes());

            int responseCode = con.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);

            System.out.println("Response Code : " + responseCode);
            if (responseCode == 200) {
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuffer response = new StringBuffer();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                System.out.println(response.toString());
            }
            //print result
            

        //} catch (Exception ex) {
        //    Logger.getLogger(KeystoreHTTPS.class.getName()).log(Level.SEVERE, null, ex);
        //}
    }
    
    public static String test() throws Exception
    {
            System.out.println("Begin");
            URL url = new URL("https://blagajne-test.fu.gov.si:9002/v1/cash_registers");
            String USER_AGENT = "Mozilla/5.0";
            String truststore = "/oracle/direktoriji/certifikati/test-tls.cer";
            String keyStore = "/oracle/direktoriji/certifikati/10031685-1.p12";
            String keyStorePassword = "Geslo123#";
            String keyPassword = "Geslo123#";
            String KeyStoreType = "PKCS12";
            String KeyManagerAlgorithm = "SunX509";
            String SSLVersion = "TLS";
            HttpsURLConnection con = getHttpsURLConnection(url, truststore, keyStore, keyStorePassword, keyPassword, KeyStoreType, KeyManagerAlgorithm, SSLVersion);
           
            //add reuqest header
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
            con.setRequestProperty("Content-type", "text/xml; charset=utf-8");
            con.setRequestProperty("SOAPAction", "\"/echo\"");

            String xml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:fu=\"http://www.fu.gov.si/\">\n"
                    + "   <soapenv:Header/>\n"
                    + "   <soapenv:Body>\n"
                    + "      <fu:EchoRequest>130031{$1}</fu:EchoRequest>\n"
                    + "   </soapenv:Body>\n"
                    + "</soapenv:Envelope>";

            con.setDoOutput(true);

            OutputStream reqStream = con.getOutputStream();

            reqStream.write(xml.getBytes());

            int responseCode = con.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);

            System.out.println("Response Code : " + responseCode);
            if (responseCode == 200) {
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuffer response = new StringBuffer();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                System.out.println(response.toString());
                return response.toString();
            }
            return null;
    }

    public static HttpsURLConnection getHttpsURLConnection(URL url,String truststore, String keystore,
            String keyStorePass, String keyPassword, String KeyStoreType, String KeyManagerAlgorithm, String SSLVersion)
            throws NoSuchAlgorithmException, KeyStoreException,
            CertificateException, FileNotFoundException, IOException,
            UnrecoverableKeyException, KeyManagementException {
        //System.setProperty("javax.net.debug", "ssl,handshake,record");

        SSLContext sslcontext = SSLContext.getInstance(SSLVersion);
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerAlgorithm);
        KeyStore ks = KeyStore.getInstance(KeyStoreType);
        ks.load(new FileInputStream(keystore), keyStorePass.toCharArray());
        kmf.init(ks, keyPassword.toCharArray());

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        
        InputStream is = new FileInputStream(truststore); //"c:/cert/test-tls.cer");
        InputStream caInput = new BufferedInputStream(is);
        Certificate ca;
        try {
            ca = cf.generateCertificate(caInput);
            System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
        } finally {
            caInput.close();
        }
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        TrustManager[] tm = tmf.getTrustManagers();

        sslcontext.init(kmf.getKeyManagers(), tm, null);
        SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory();
        HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
        HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();

        return httpsURLConnection;
    }

    public static void main(String[] args) throws FileNotFoundException {
        try {
            KeystoreHTTPS a = new KeystoreHTTPS();
        } catch (Exception ex) {
            Logger.getLogger(KeystoreHTTPS.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}



Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Davčne blagajne (strani: 1 2 3 424 25 26 27 )

Oddelek: Programiranje
1344318621 (58624) Macketina
»

[Java] Zasnova shoot em up igre

Oddelek: Programiranje
111104 (783) PecenkA
»

[java] system.setproperty xml apis vec implementacij naenkrat

Oddelek: Programiranje
52594 (2053) Fizikalko
»

java ws problem

Oddelek: Programiranje
6941 (824) pujs
»

[Java]Brane spletne strani preko https

Oddelek: Programiranje
112034 (1853) CWIZO

Več podobnih tem