I built a client-server SSL app in which I want to make some tests but I have problem with the client. The server is running ok, but when I try to run the client I have this message:
Exception in thread "main" 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
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
at sun.security.ssl.AppOutputStream.write(Unknown Source)
at java.io.OutputStream.write(Unknown Source)
at ssl.Client.main(Client.java:17)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 10 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 16 more
Server:
package ssl;
import java.io.PrintStream;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
public class Server {
private static final String HOST = "localhost";
private static final int PORT = 3443;
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "DebKeyStore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "iliebc");
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket ss = ssf.createServerSocket(PORT, 0, InetAddress.getByName(HOST));
System.out.println("Server started on port " + PORT);
while (true) {
Socket s = ss.accept();
SSLSession session = ((SSLSocket) s).getSession();
//System.out.println(session.getLocalCertificates());
Certificate[] cchain2 = session.getLocalCertificates();
for (int i = 0; i < cchain2.length; i++) {
System.out.println(((X509Certificate) cchain2[i]).getSubjectDN());
}
System.out.println("Peer host is " + session.getPeerHost());
System.out.println("Cipher is " + session.getCipherSuite());
System.out.println("Protocol is " + session.getProtocol());
System.out.println("ID is " + new BigInteger(session.getId()));
System.out.println("Session created in " + session.getCreationTime());
System.out.println("Session accessed in " + session.getLastAccessedTime());
PrintStream out = new PrintStream(s.getOutputStream());
out.println("Hi");
out.close();
s.close();
}
}
}
Client:
package ssl;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.ssl.SSLSocketFactory;
public class Client {
private static final String HOST = "localhost";
private static final int PORT = 3443;
public static void main(String[] args) throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket socket = sf.createSocket(InetAddress.getByName(HOST), PORT);
OutputStream out = socket.getOutputStream();
System.out.println(out);
out.write("\nConnection established.\n\n".getBytes());
out.flush();
int theCharacter = 0;
theCharacter = System.in.read();
while (theCharacter != '~') { // The '~' is an escape character to exit
out.write(theCharacter);
out.flush();
theCharacter = System.in.read();
}
out.close();
socket.close();
}
}
How may I solve this exception?
Solution:
System.setProperty("javax.net.ssl.keyStore", "DebKeyStore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "iliebc");
System.setProperty("javax.net.ssl.trustStore", "DebKeyStore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "iliebc");
Related
Grrr, I feel that this should be so obvious yet I can't find the solution.
For testing purposes I have created a simple Client and Server for an RMI application. I can successfully run the client and server over a local network. I can also successfully run the application when connected through a Windows 10 Built-In VPN connection. However, when connected via an OpenVPN connection I receive a Connection refused to host exception when calling a method (String response = lookup.helloTo(txt); in the Client code) on the remote object returned from the successful call to lookup = (RMIInterface)Naming.lookup("//192.168.10.14/MyServer");.
All my Google searches state that the java.rmi.server.hostname property must be set which I have done in this case. I am thinking that the issue may be between the VPN client IP address (10.8.0.14) and the server IP address (192.168.10.14). I can ping the server IP address and telnet to port 1099 on the server successfully.
Here is my code. I was hoping if someone could see something that I am missing or doing wrong or if I am on the right track regarding the VPN Client IP <=> Server IP.
Remote Interface:
package devel;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIInterface extends Remote {
public String helloTo(String name) throws RemoteException;
}
Server:
package devel;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ServerOperation extends UnicastRemoteObject implements RMIInterface {
private static final long serialVersionUID = 1L;
protected ServerOperation() throws RemoteException {
super();
}
#Override
public String helloTo(String name) throws RemoteException {
System.err.println(name + " is trying to contact!");
return "Server says hello to " + name;
}
public static void main(String[] args) {
try {
java.lang.System.setProperty("java.rmi.server.hostname", "192.168.10.14");
java.rmi.registry.LocateRegistry.createRegistry(1099);
Naming.rebind("//192.168.10.14/MyServer", new ServerOperation());
System.err.println("Server is ready");
} catch(Exception exc) {
System.err.println("Server exception: " + exc.toString());
exc.printStackTrace();
}
}
}
Client:
package devel;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import javax.swing.JOptionPane;
public class ClientOperation {
private static RMIInterface lookup;
public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
lookup = (RMIInterface)Naming.lookup("//192.168.10.14/MyServer");
String txt = JOptionPane.showInputDialog("What is your name?");
String response = lookup.helloTo(txt);
JOptionPane.showMessageDialog(null, response);
}
}
Exception received:
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: 192.168.10.14; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.helloTo(Unknown Source)
at devel.ClientOperation.main(ClientOperation.java:17)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
... 8 more
I have been trying to connect Bitly REST API using Java. I want to use shorten method from Bitly API. Here is my code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.BasicConfigurator;
public class PostRequestClient {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
BasicConfigurator.configure();
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"https://api-ssl.bitly.com/v3/shorten");
StringEntity input = new StringEntity("{\"access_token\":<my_access_token>,\"longUrl\":\"https://docs.appian.com/suite/help/18.1/Custom_Function_Plug-ins.html\"}");
input.setContentType("application/json");
postRequest.setEntity(input);
HttpResponse response = httpClient.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
httpClient.getConnectionManager().shutdown();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have referenced this code from https://www.mkyong.com/webservices/jax-rs/restful-java-client-with-apache-httpclient/. Please let me know your thoughts whether I am calling the bitly api correctly or not.
I am getting following error:
0 [main] DEBUG org.apache.http.impl.conn.SingleClientConnManager - Get connection for route HttpRoute[{s}->https://api-ssl.bitly.com]
31 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnectionOperator - Connecting to api-ssl.bitly.com/XX.XXX.XXX.21:443
21059 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnectionOperator - Connect to api-ssl.bitly.com/XX.XXX.XXX.21:443 timed out. Connection will be retried using another IP address
21059 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnectionOperator - Connecting to api-ssl.bitly.com/XX.XXX.XXX.20:443
42080 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection - Connection closed
org.apache.http.conn.HttpHostConnectException: Connection to https://api-ssl.bitly.com refused
42080 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection - Connection shut down
42080 [main] DEBUG org.apache.http.impl.conn.SingleClientConnManager - Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter#7225790e
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:158)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:562)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at com.persistent.plugins.urlshortener.PostRequestClient.main(PostRequestClient.java:70)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:374)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
... 8 more
I would appreciate if you could give me some inputs to fix this error.
Thank you!
I was learning socket programming in Java and had written a simple program for connecting a client server to a socket server on a local host. But every time when I run the ClientServer program it gives an error stating connection :refused.
I am enclosing both the client code and server code that i wrote and also enclosing the console output.
package Classes;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientSer {
/**
* #param args
* #throws IOException
* #throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Socket s = new Socket("localhost",1029);
OutputStreamWriter os = new OutputStreamWriter(s.getOutputStream());
String str = "tEST mESSAGE";
os.write(str);
os.flush();
}
}
This is the server code:
package Classes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketSer {
public static void main(String args[]) throws Exception{
ServerSocket ss = new ServerSocket(1029);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = br.readLine();
System.out.print(str);
}
}
Console output:
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Classes.ClientSer.main(ClientSer.java:18)
In the server, do you know what interface it's listening on?
I would start the server and then use telnet to try to connect rather than your client. You might find the server is NOT listening on localhost. Or maybe it's listening on every interface (127.0.0.1 plus your local network). I just don't know if I trust SocketServer(portNumber).
I would consider creating an unbound SocketServer and then use socket.bind(), feeding it an InetSocketAddress object constructed with both host and port.
I am working on messaging over sockets on my local machine. I am trying to message myself, which is emulating me messaging over the internet. Anyhow, I had gotten a bind exception earlier but it seems I may have gotten past that. Now I am getting the :
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at class2.main(class2.java:10)
How do I get this connection to work and my messages to pass. Here are the two classes in my program:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class IPMessenger {
public static void main(String[] args) throws IOException{
ServerSocket SC = new ServerSocket(4800);
Socket socket = SC.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.println(in.readDouble());
System.out.println("hi");
// out.writeChars("hello");
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class class2 {
public static void main(String[] args) throws UnknownHostException, IOException{
Socket sock = new Socket("localhost",4800);
DataInputStream in = new DataInputStream(sock.getInputStream());
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
out.writeDouble(5);
//System.out.println(in.readChar());
}
}
java.net.ConnectException: Connection refused: connect
Your server isn't running when you run the client.
Use Case:
There is a web service posted as https://a.b.c.d/zz?wsdl
What i would like to do is to query this URI and IF i get a VALID WSDL, i return a boolean "true" else "false.
Now, if i go via Chrome browser to this URL, i would have to manually do an accept on the cert warning, and THEN the WSDL gets downloaded. But how can do this via Java / HttpsURLConnection
import java.net.URL;
import java.io.*;
import javax.net.ssl.HttpsURLConnection;
public class JavaHttpsExample
{
public static void main(String[] args)
throws Exception
{
String httpsURL = "https://a.b.c.d/zz/V2.0/api?wsdl";
URL myurl = new URL(httpsURL);
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
InputStream ins = con.getInputStream();
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader in = new BufferedReader(isr);
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println(inputLine);
}
in.close();
}
}
and i get an error:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException: No subject alternative names
matching IP address a.b.c.d found at
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown
Source) at
com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown
Source) at
com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown
Source) at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown
Source) at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown
Source) at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown
Source) at
sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown
Source) at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source) at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown
Source) at JavaHttpsExample.main(JavaHttpsExample.java:14) Caused by:
java.security.cert.CertificateException: No subject alternative names
matching IP address a.b.c.d found at
sun.security.util.HostnameChecker.matchIP(Unknown Source) at
sun.security.util.HostnameChecker.match(Unknown Source) at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(Unknown
Source) at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown
Source)
i have replaced the real IP with a.b.c.d (of course)
Don't use a stubbed out TrustManager as this makes your application trust everyone. I would recommend downloading the certificate presented by the site and adding it to a private, trusted keystore. This lets you make an exception for that one site without greenlighting everyone.
I also like this approach because it requires no code changes.
In Chrome, click the lock icon to the left of the url. Then click "Certificate Information". Go to the "Details" tab and click "Copy to file". Save it as a "base64 encoded X.509 (.cer)" to "SITENAME.cer".
Copy $JAVA_HOME/lib/security/cacerts to your application's directory as "mykeystore.jks".
Install the certificate with:
keytool -keystore mykeystore.jks -storepass changeit -importcert -alias SITENAME -trustcacerts -file SITE.cer
Now, when you run your application, tell it to use the private certificate store:
java -Djavax.net.ssl.trustStore=mykeystore.jks ...
Just Implement your own trust manager like in the below code
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.io.*;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class JavaHttpsExample
{
public static void main(String[] args)
throws Exception
{
String httpsURL = "https://a.b.c.d/zz?wsdl";
URL myurl = new URL(httpsURL);
SSLContext ssl = SSLContext.getInstance("TLSv1");
ssl.init(null, new TrustManager[]{new SimpleX509TrustManager()}, null);
SSLSocketFactory factory = ssl.getSocketFactory();
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
con.setSSLSocketFactory(factory);
InputStream ins = con.getInputStream();
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader in = new BufferedReader(isr);
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println(inputLine);
}
in.close();
}
}
class SimpleX509TrustManager implements X509TrustManager {
public void checkClientTrusted(
X509Certificate[] cert, String s)
throws CertificateException {
}
public void checkServerTrusted(
X509Certificate[] cert, String s)
throws CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
}