Forum » Programiranje » [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.
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 (???)
- 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);
}
}
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?
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
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?
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.
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.
Č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
Using JSSE for secure socket communication
Še izvorna koda primerov v tutorialu: jsse-source.zip
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...
Š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č.
@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 ::
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);
}
}
}
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);
}
}
}
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 ;-)
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...
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 ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Davčne blagajne (strani: 1 2 3 4 … 24 25 26 27 )Oddelek: Programiranje | 333540 (73543) | Macketina |
» | [Java] Zasnova shoot em up igreOddelek: Programiranje | 1198 (877) | PecenkA |
» | [java] system.setproperty xml apis vec implementacij naenkratOddelek: Programiranje | 2700 (2159) | Fizikalko |
» | java ws problemOddelek: Programiranje | 1017 (900) | pujs |
» | [Java]Brane spletne strani preko httpsOddelek: Programiranje | 2148 (1967) | CWIZO |