SSL socket connection between PHP client and Java server - java

I'm attempting to setup an SSL connection between a PHP client and a Java server. I don't know a whole lot about SSL and I'm getting very confused with this.
The connection doesn't need to be trusted or verified, it just has to encrypt the data to make it safe for transfer.
The PHP client is able to connect (acknowledges a connection) to the Java server, but upon the handshake between the two, I reveive the following error in Java:
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1458)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:92)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at com.test.ConnectionHandler.getRequest(ConnectionHandler.java:23)
at com.test.Interaction.run(Interaction.java:35)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266)
at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:892)
at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:620)
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:167)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.io.BufferedWriter.flush(BufferedWriter.java:254)
at java.io.PrintWriter.newLine(PrintWriter.java:482)
at java.io.PrintWriter.println(PrintWriter.java:629)
at java.io.PrintWriter.println(PrintWriter.java:740)
at com.test.ConnectionHandler.println(ConnectionHandler.java:28)
at com.test.Interaction.run(Interaction.java:29)
... 1 more
and these errors in PHP:
Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:14077410:SSL routines:func(119):reason(1040) in /var/www/html/inc/node.class.php on line 48
Warning: fsockopen(): Failed to enable crypto in /var/www/html/inc/node.class.php on line 48
Warning: fsockopen(): unable to connect to ssl://127.0.0.1:30627 (Unknown error) in /var/www/html/inc/node.class.php on line 48
This is my code in Java which handles the socket setup:
SSLServerSocketFactory socketfactory;
SSLServerSocket ssock;
SSLContext sslContext = SSLContext.getInstance( "SSL" );
KeyStore ks = KeyStore.getInstance("JKS");
InputStream ksIs = ClassLoader.class.getResourceAsStream("resources/keystore.jks");
try {
ks.load(ksIs, "password".toCharArray());
} catch (CertificateException e) {
e.printStackTrace();
} finally {
if (ksIs != null) {
ksIs.close();
}
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "password".toCharArray());
sslContext.init( kmf.getKeyManagers(), null, null );
socketfactory = sslContext.getServerSocketFactory();
socketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ssock = (SSLServerSocket) socketfactory.createServerSocket(myPort);
for(String item : ssock.getEnabledCipherSuites()) {
System.out.println(item);
}
while(true) {
SSLSocket sock = (SSLSocket) ssock.accept();
new Interaction(sock);
}
This is my PHP code which handles the connection to the Java server:
(Starting at line 48)
$this->stream = fsockopen("ssl://127.0.0.1", 30627, $errno, $errstr);
if(!$this->stream) {
return array(
'errornum' => $errno,
'errorstr' => $errstr,
);
} else {
return true;
}
Can someone help explain what I'm doing wrong or provide a solution?
--Edit
I've tried using a Java client to connect to see where the problem lies. But I still receive the same error and this is shown on the Java Client:
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHands
hakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.jav
a:1293)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.j
ava:1305)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.ja
va:43)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
at java.io.BufferedWriter.flush(BufferedWriter.java:236)
at Main.main(Main.java:55)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_
failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.ja
va:1720)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.j
ava:954)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SS
LSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketIm
pl.java:753)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:
75)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at Main$Output.run(Main.java:77)
at java.lang.Thread.run(Thread.java:662)

I figured out that the problem was with loading the keystore. The way I was retrieving it as a resource wasn't working.
I got the keystore to load correctly and everything then worked fine.

Related

SSL Socket Connection Error

I am using JAVA 8. I am trying to connect a Socket Server using client certificates and certificate tree.
I have followings provided by client:
Client CERT (PEM)
Private Key (PEM)
CA Tree (PEM) - with 4 Certificates
I have created keystore.jks using following steps:
Combining client cert and CA tree in a single pem file using cat
Crested PKCS12 file from combined file encrypted using private key(OpenSSL Command)
Generated JKS keystore file using keytool
I have created trustore.jks using following steps:
Split CA Tree (4 certificates) into 4 different files
Generated trustore file using keytool by importing each file one by one
My Sample code is as following :
package com.tutorial.exception.customize;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.util.Scanner;
/**
* Created by SomnathG on 12/1/2016.
*/
public class Client {
public Client() {
System.setProperty("javax.net.ssl.keyStore", {keystore Location});
System.setProperty("javax.net.ssl.keyStorePassword", {password});
System.setProperty("javax.net.ssl.trustStore", {trustore location});
System.setProperty("javax.net.ssl.trustStorePassword", {password});
System.setProperty("javax.net.debug", "all");
System.setProperty( "sun.security.ssl.allowUnsafeRenegotiation", "true" );
}
public void connectHost(){
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = null;
try {
sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
sslSocket.startHandshake();
InputStream inputStream = sslSocket.getInputStream();
OutputStream outputStream = sslSocket.getOutputStream();
System.out.println("Sending request to Socket Server");
outputStream.write("Hello".getBytes());
outputStream.write("exit".getBytes());
byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
int bytesRead = 0;
String messageString = "";
DataInputStream in = new DataInputStream(sslSocket.getInputStream());
while(!end)
{
bytesRead = in.read(messageByte);
messageString += new String(messageByte, 0, bytesRead);
if (messageString.length() == 100)
{
end = true;
}
}
System.out.println("MESSAGE: " + messageString);
// byte[] read = (byte[]) ois.readObject();
//String s2 = new String(read);
//System.out.println("" + s2);
//System.out.println("Message: " + message);
//close resources
//System.out.println(receive(inputStream));
}catch (IOException e) {
e.printStackTrace();
System.out.println("=====");
System.out.println(e.getMessage());
System.out.println("=====");
CertPathValidatorException ce = new CertPathValidatorException(e);
System.out.println("******");
System.out.println(ce.getIndex());
System.out.println(ce.getReason());
System.out.println("******");
//e.printStackTrace();
}
}
public static void main(String[] args){
new Client().connectHost();
}
}
I am getting following exception after executing the code:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: basic constraints check failed: this is not a CA certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at com.tutorial.exception.customize.Client.connectHost(Client.java:33)
at com.tutorial.exception.customize.Client.main(Client.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
After analyzing the log I have found "clientHello" and "serverHello" messages but after that application is throwing above mentioned exception.
What am I doing wrong? Please advice.
Thanks,
Somnath Guha
I have figured out the issue after analyzing the debug lo.
"BasicConstraints" was missing from the server V3 certificates and thus java was failing to recognize the certificate as a valid certificate. Once that constraint has been added then the client was able to handshake with the server and able to communicate with server.
BasicConstraints:[
CA:true
PathLen:2147483647
]

Paypal Sandbox API: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

I am getting an exception while using PayPal MassPay API in sandbox mode.
The same code worked earlier, now it is giving me an SSLHandshakeException. I think this is because of PayPal's latest SSL certification updates. Could someone can help me fix this issue?
The following is my exception log:
http-bio-9090-exec-1, READ: TLSv1 Alert, length = 2
http-bio-9090-exec-1, RECV TLSv1 ALERT: fatal, handshake_failure
http-bio-9090-exec-1, called closeSocket()
http-bio-9090-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
com.paypal.core.rest.PayPalRESTException: Received fatal alert: handshake_failure
at com.paypal.core.rest.PayPalResource.execute(PayPalResource.java:374)
at com.paypal.core.rest.PayPalResource.configureAndExecute(PayPalResource.java:225)
at com.paypal.sdk.openidconnect.Tokeninfo.createFromAuthorizationCode(Tokeninfo.java:245)
at com.oldwallet.controllers.CouponPaymentController.redeemed(CouponPaymentController.java:321)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at com.paypal.core.HttpConnection.execute(HttpConnection.java:93)
at com.paypal.core.rest.PayPalResource.execute(PayPalResource.java:367)
... 36 more
The issue is that PayPal recently (19th or 20th of Jan) switched the sandbox to TLS 1.2 and do not support TLS 1 anymore. I guess that you are running on Java SE 7 or older. If you search the net a bit you will find this:
Although SunJSSE in the Java SE 7 release supports TLS 1.1 and TLS
1.2, neither version is enabled by default for client connections. Some servers do not implement forward compatibility correctly and
refuse to talk to TLS 1.1 or TLS 1.2 clients. For interoperability,
SunJSSE does not enable TLS 1.1 or TLS 1.2 by default for client
connections.
Link
To enable TLS 1.2 you can use the following setting of the VM: -Dhttps.protocols=TLSv1.1,TLSv1.2 Then it will work.
If you want to see more details about the handshake you can use this VM option: -Djavax.net.debug=all
Then you may confirm that TLS 1.2 is disabled if you see something like this:
*** ClientHello, TLSv1
After the server response is read the exception will be thrown. Java 8 has no such problem because TLS 1.2 is enabled by default.
Currently only the sandbox is affected. You can read on PayPal's site:
PayPal is updating its services to require TLS v1.2 for all HTTPS
connections on June 17, 2016. After that date, all TLS v1.0 and TLS
v1.1 API connections will be refused.
Most likely this will be postponed even more.
You may reproduce the problem and experiment with this simple throw-away code:
URL sandbox = new URL("https://api.sandbox.paypal.com/v1/oauth2/token");
URLConnection yc = sandbox.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
http-bio-9090-exec-1, RECV TLSv1 ALERT: fatal, handshake_failure
Looks like you're using an older version of TLS. PayPal recently (a few days ago) made a change to their sandbox to require all connections be done over HTTP 1.1 and TLS 1.2. Try setting your code to use the newer version of TLS (1.2) and see if that helps. Apparently it's worked for a lot of people on here.
Link to the change description on PayPal dev blog
https://devblog.paypal.com/upcoming-security-changes-notice/
I have been dealing with the same problem (Paypal TLS 1.2 Vs JRE 1.6) this week. After some crazy hours, I managed to solve the problem using BouncyCastle and a some code I am not proud of (just as a patch. lasting solution will be upgrading to JRE 1.8).
BouncyCastle dependency:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.54</version>
</dependency>
My working code:
package es.webtools.eencuesta.redsys.component.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.bouncycastle.crypto.tls.CertificateRequest;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsCredentials;
import es.webtools.eencuesta.common.util.HttpUtils;
public class PayPayAPIHandler {
public static Map<String, String> doAPIRequest(Map<String, String> paramMap) {
StringBuilder data = new StringBuilder();
Iterator<Entry<String, String>> paramIt = paramMap.entrySet().iterator();
while (paramIt.hasNext()) {
Entry<String, String> param = paramIt.next();
data.append(param.getKey()).append("=").append(HttpUtils.encodeUTF8(param.getValue()));
if (paramIt.hasNext()) {
data.append("&");
}
}
try {
URL url = new URL("https://api-3t.sandbox.paypal.com/nvp");
// TODO #39 Utilizar HttpConnection (Java 8 implementa TLS 1.2, necesaria para comunicación con PayPal)
java.security.SecureRandom secureRandom = new java.security.SecureRandom();
Socket socket = new Socket(java.net.InetAddress.getByName(url.getHost()), 443);
TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), secureRandom);
DefaultTlsClient client = new DefaultTlsClient() {
public TlsAuthentication getAuthentication() throws IOException {
TlsAuthentication auth = new TlsAuthentication() {
// Capture the server certificate information!
public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException {
}
public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException {
return null;
}
};
return auth;
}
};
protocol.connect(client);
java.io.OutputStream output2 = protocol.getOutputStream();
output2.write(("POST " + url.getPath() + " HTTP/1.1\r\n").getBytes("UTF-8"));
output2.write(("Host: " + url.getHost() + "\r\n").getBytes("UTF-8"));
output2.write("Connection: close\r\n".getBytes("UTF-8")); // So the server will close socket immediately.
output2.write(("Content-Length: " + data.length() + "\r\n").getBytes("UTF-8")); // So the server will close socket immediately.
output2.write("Content-Type:text/plain; charset=UTF-8\r\n".getBytes("UTF-8")); // So the server will close socket immediately.
output2.write("\r\n".getBytes("UTF-8")); // HTTP1.1 requirement: last line must be empty line.
output2.write(data.toString().getBytes("UTF-8"));
output2.flush();
InputStream input2 = protocol.getInputStream();
StringBuilder stringBuffer = new StringBuilder();
try {
InputStreamReader reader = new InputStreamReader(input2, "UTF-8");
int ch;
while ((ch = reader.read()) > -1) {
stringBuffer.append((char) ch);
}
reader.close();
} catch (Exception e) {
// Log some messages...
}
Map<String, String> result = new HashMap<String, String>();
String[] lines = stringBuffer.toString().split("\r\n");
String paramsLine = "";
for (int i = 0; i < lines.length; i++) {
if (lines[i].equals("")) {
paramsLine = lines[i + 1];
i = lines.length;
}
}
// El contenido de la respuesta vendrá después del salto de linea
for (String param : paramsLine.split("&")) {
String[] keyValue = param.split("=");
result.put(keyValue[0], URLDecoder.decode(keyValue[1], "UTF-8"));
}
return result;
} catch (Exception e) {
// Log some messages....
return null;
}
}
}
If you are calling https request from a web service or in a standalone application in JAVA, use the following line to make it work :
System.setProperty(“https.protocols”, “TLSv1,TLSv1.1,TLSv1.2”);
My problem was that I had java 7 installed so I upgraded to java 8 and voila, the exception was not there anymore :)

Error when sending email in Java

I have a problem with sending emails in Java. I am using the JavaMail api to send emails. I have a program which downloads an email attachment using pop3, reads the content, does some manipulation and then sends the result in an email using smtp.
The program works fine until the last step where it sends the email and I get the following exception.
javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 25;
nested exception is:
java.net.ConnectException: Connection refused: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1961)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:654)
at javax.mail.Service.connect(Service.java:295)
at javax.mail.Service.connect(Service.java:176)
at javax.mail.Service.connect(Service.java:125)
at javax.mail.Transport.send0(Transport.java:194)
at javax.mail.Transport.send(Transport.java:124)
at com.adidas.monitoring.SendMail.sendMail(SendMail.java:46)
at com.adidas.monitoring.MainClass.main(MainClass.java:115)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(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 com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:321)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:237)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1927)
I am using the following code to send the email
public void sendMail(String strMailContent)
{
MimeMessage emailMessage;
Properties emailProperties = new Properties();
try {
emailProperties.load(new FileInputStream("Email.ini"));
} catch (IOException e){
DataLogger.logger.error(e.getMessage());
}
/*Get the properties from the email configuration file*/
String From = emailProperties.getProperty("Email.From");
String ToAdd = emailProperties.getProperty("Email.To");
String CC = emailProperties.getProperty("Email.CC");
String Subject = emailProperties.getProperty("Email.Subject");
String Host = emailProperties.getProperty("Email.Gateway");
emailProperties.setProperty("mail.smtp.host", Host);
Session emailSendSession = Session.getDefaultInstance(emailProperties);
try{
emailMessage = new MimeMessage(emailSendSession);
emailMessage.setFrom(new InternetAddress(From));
emailMessage.addRecipients(javax.mail.Message.RecipientType.TO,ToAdd);
emailMessage.addRecipients(javax.mail.Message.RecipientType.CC,CC);
emailMessage.setSubject(Subject);
emailMessage.setText(strMailContent);
Transport.send(emailMessage);
}
catch (Exception mailEx)
{
mailEx.printStackTrace();
}
}
The above code works fine when I use it with other programs. But when I am using it along with the pop3 code in this case, I have this error. Strange thing is the host is shown as localhost even though I set the property "mail.smtp.host".
Any help on this topic is really appreciated.

Java Client/Server SSL Socket Chat

Ok pals, so I have created a java chat using TCP client/server socket.
I create the server, and then i create clients that connect to the server so that they can communicate between each other through the server!
The code: Server:
public ServerChat() throws Exception{
ServerSocket soc=new ServerSocket(5217);
while(true)
{
Socket CSoc=soc.accept();
//and then the code for handling the messages, we don't need that
}
}
And the client:
Server soc=new Socket("127.0.0.1",5217);
Thread t=new Thread(this);
t.start();
//i Have ommited many parts of the code, but you know, i focus on the connection part of the problem!`
So now, I want to use SSL protection(so i can see the changes in wireshark).
I used OpenSSL(it is required for my assingment) to create a root CA and device certificates.I put the files on the src folder on netbeans, and copied the code to two new classes, SSLServer and SSLClient, and experimented a bit on the SSL part! So:
public SSLServer() throws Exception{
SSLContext sslContext=????//supposed to add the files somehow here?
SSLServerSocketFactory factory=(SSLServerSocketFactory)slContext.getServerSocketFactory();
SSLServerSocket sslserversocket=(SSLServerSocket) factory.createServerSocket(1234);
while(true)
{
SSLSocket sslsocket=(SSLSocket)sslserversocket.accept();
}
}
Same thing for the client. So I am a bit stuck on the SSLContext part! I read many threads here but still..
Is the part below SSLContext correct? And how do I use the certificates in SSLContext?
EDIT: Maybe this will work? :
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("keystoreFile"), "keystorePassword".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(ks, "keystorePassword".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(ks);
SSLContext sc = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
sc.init(kmf.getKeyManagers(), trustManagers, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(serverport);
SSLSocket c = (SSLSocket) s.accept();
anyway, i found some links that helped me!
if anyone is interested,
importing an existing x509 certificate and private key in Java keystore to use in ssl
http://www.agentbob.info/agentbob/79-AB.html

Fail to connect to james server localhost

I'm trying to connect to James server localhost, but I'm getting an exception
javax.mail.MessagingException: Could not connect to SMTP host: localhost, port:25;
nested exception is:
java.net.SocketException: Network is unreachable: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1545)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:453)
at javax.mail.Service.connect(Service.java:313)
at javax.mail.Service.connect(Service.java:172)
at javax.mail.Service.connect(Service.java:121)
at javax.mail.Transport.send0(Transport.java:190)
at javax.mail.Transport.send(Transport.java:120)
at mail.main(mail.java:78)
Caused by: java.net.SocketException: Network is unreachable: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(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 com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:267)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:227)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1511)
... 7 more
The directory structure of my James Server is:
C:\apache-james-2.3.2
|
|
|
|------C:\apache-james-2.3.2\james-2.3.2
|
|------C:\apache-james-2.3.2\javamail-1.4.2
|
|------C:\apache-james-2.3.2\jaf-1.0.2
Here's the code, which is throwing an exception:
I've not changed anything in the config file of james-2.3.2 subdirectory, then why I'm
getting that exception?
Here's the code, which is throwing an exception:
// imports omitted
public class mail {
public static void main(String[] args) {
String to = "blue#localhost";
String from = "red#localhost";
String subject = "Hello";
String body = "What's up";
if ((from != null) && (to != null) && (subject != null) && (body != null)) {
try { // we have mail to send
Properties props = new Properties();
props.put("mail.host", "localhost");
props.put("mail.smtp.auth", "true");
props.put("mail.debug", "true");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("red", "red");
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
Address[] add = { new InternetAddress(to) };
message.setRecipients(Message.RecipientType.TO, add);
message.setSubject(subject);
message.setContent(body, "text/plain");
message.setText(body);
Transport.send(message);
System.out.println(" Your message to " + to + " was successfully sent.");
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
The exception is saying that localhost is unreachable. I expect that your machine does not have its loopback network address (localhost / 127.0.0.1) correctly configured.
EDIT: I assume that you are running the client and server on the same machine. If not, you cannot use localhost / 127.0.0.1.
I always try to telnet to port 25 on the mailhost, to check if the server can be reached. Try to connect to 127.0.0.1 to check if James is accepting incoming connections. I presume you have checked the logs of James for errors?
Try using the IP address 127.0.0.1 instead of the hostname 'localhost' - maybe DNS lookup on your machine is not set up properly, so that it doesn't know what the name 'localhost' means.
Open the file C:\Windows\System32\drivers\etc\hosts, and make sure it contains a line like this:
127.0.0.1 localhost
Also, try switching off your firewall or anti-virus software.
try to start apache james as root user in linux or start as
Administrator on windows. and check the server is successfully
started or not on james-server.log file in logs folder
add the host name on your hosts file
127.0.0.1 localhost
file placed
on linux /etc/hosts
on windows C:\Windows\System32\drivers\etc\hosts
and restart your server.

Categories

Resources