I have HttpsURLConnection opened.
How can i "connect" my ssl socket to this connection, means not to do another ssl handshake and don't change my ciphers.
URL url = new URL ("https://example.com:8080");
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.connect();
SSLSocketFactory ssf = connection.getSSLSocketFactory();
SSLSocket socket = (SSLSocket) ssf.createSocket("example.com", 8080);
// and here i want to send message with socket which will be in the same ssl session as https connection.
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
out.write("Hello");
out.flush();
out.close();
Is it really to do such thing in Java?
It should happen that way by default, as long as the session remains valid, and provided you haven't messed around with SSLContexts.
AFAIK, you cannot attach a new socket to the existing SSL session. If you want to send/read data on the original SSL session, use the original socket connection created by the URLConnection object. You can use the URLConnection.getInputStream() and URLConnection.getOutputStream() methods to get the input/output streams for it:
URL url = new URL ("https://example.com:8080");
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.connect();
...
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
out.write("Hello");
out.flush();
out.close();
Related
I've just worked out how to install a Lets Encrypt certificate on my server, so my browsers now show my site to be secure when I access via https://.
When I try to access my server end points in a Java client application using the following,
URL httpsURL = new URL(urlStringServerEndPoint);
sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, new java.security.SecureRandom());
conn = (HttpsURLConnection) httpsURL.openConnection();
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStream os = conn.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
osw.write(dataString);
osw.flush();
osw.close();
os.close();
conn.connect();
if(conn.getResponseCode() != 200)
throw new MyServerException();
this also works.
But - if I remove the certificate from my server and run the Java client again it still works. Surely it should throw up an error saying there's no certificate shouldn't it? What am I doing wrong?
I have a client/server pair in which I have this messaging application to which i'm trying to add SSL support. The client/server normally use DataInputStream and DataOutputStream to send/receive their info, working with byte arrays (DataOutputStream.write(byte[]) and DataInputStream.readFully(byte[])). But for some reason, that doesn't work with SSL sockets. I've tried using DataOutputStream.writeUTF() and DataInputStream.readUTF() and it works. I even tried using other types of reader/writers like BufferedReader/BufferedWriter, and they work, but when I try to use bytes, it doesn't send anything. What's weirder is the fact that after checking the DataOutputStream.size() in both sides, they both print that they have sended data.
Server side:
logger.info("Waiting to accept a new client socket");
clientSocket = (SSLSocket) serverSocket.accept();
logger.info("Socket accepted successfully");
DataOutputStream dataOutputStream=newDataOutputStream(clientSocket.getOutputStream());
DataInputStream dataInputStream=new DataInputStream(clientSocket.getInputStream());
logger.trace("Socket is going to read");
int data=dataInputStream.available();
byte[] message=new byte[data];
dataInputStream.readFully(message);
logger.trace("Message received: {}",message);
logger.trace("Gonna respond");
if(message.length>0){
dataOutputStream.write(message,0,message.length);
}else{
String response=new String("wot?".getBytes(),"ASCII");
dataOutputStream.write(response.getBytes(),0,response.getBytes().length);
}
dataOutputStream.flush();
logger.trace("Chars written: {}",dataOutputStream.size());
Client side:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
logger.trace("SSL Socket factory created");
javax.net.ssl.SSLSocket sslSocket = (javax.net.ssl.SSLSocket)sslsocketfactory.createSocket(url, port);
logger.trace("SSL Socket created");
sslSocket.setSoTimeout(6000);
outputStream = sslSocket.getOutputStream();
inputStream=sslSocket.getInputStream();
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
DataInputStream dataInputStream=new DataInputStream(inputStream);
logger.trace("Input and output created");
//dataOutputStream.writeBytes(frame);
//dataOutputStream.writeUTF(frame);
dataOutputStream.write(frame.getBytes(),0,frame.getBytes().length);
dataOutputStream.flush();
logger.trace("Frame {} sent",frame);
logger.trace("Bytes sent: {}",dataOutputStream.size());
int data=dataInputStream.available();
byte[] messageRead = new byte[data];
dataInputStream.readFully(messageRead);
Any help would be highly appreciated. I've been looking around and I don't know what else to try.
I'm creating a android proxy server and i use this for HTTP request :
Socket socket = new Socket(InetAddress.getByName("perdu.com"), 80);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.print("GET / HTTP/1.1\r\nHost: perdu.com\r\nConnection: close\r\n\r\n");
out.flush();
I doesn't work for HTTPS request, so my question is : How to replace this for SSL working and get server response ?
Thank you
PS: i'm french, sorry for my english :)
I found solution
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) factory.createSocket(domain, 443);
socket.startHandshake();
BufferedReader in = new BufferedReader(new InpuStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
My app is based on Sockets, but regular Sockets, not SSLSockets. Do I have to change all of them to SSL sockets to be able connect to https server?
You must change how the socket is created, by using the SSLSocketFactory, but you don't have to change all your datatypes from Socket to SSLSocket.
Yes i think you have to change for SSL, you can try that :
System.setProperty("javax.net.ssl.trustStore", "clienttrust");
SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket s = ssf.createSocket("127.0.0.1", 8888);
OutputStream outs = s.getOutputStream();
PrintStream out = new PrintStream(outs);
InputStream ins = s.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(ins));
out.println("Hi,How are u!");
out.println("");
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
out.close();
it's from : http://www.java2s.com/Tutorial/Java/0490__Security/HttpsSocketClient.htm
Hope it helps !
I write FTPS server, and I have problems with ssl connection after AUTH TLS command.
Simple example:
try
{
int ServerPort = 21;
ServerSocket FtpExServer = new ServerSocket(ServerPort);
while(true)
{
Socket S = FtpExServer.accept();
InputStreamReader ISR = new InputStreamReader(S.getInputStream());
OutputStreamWriter OSW = new OutputStreamWriter(S.getOutputStream());
BufferedReader ClientSocketReader = new BufferedReader(ISR);
PrintWriter ClientSocketWriter = new PrintWriter(OSW, true);
ClientSocketWriter.println("220 Welcome to FTP server.");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("234 AUTH TLS successful");
char[] passphrase = "pass".toCharArray();
char[] cpassphrase = "cpass".toCharArray();
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("keystore.jks"), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, cpassphrase);
SSLContext context = SSLContext.getInstance("TLS");
KeyManager[] keyManagers = kmf.getKeyManagers();
context.init(keyManagers, null, null);
SSLServerSocketFactory ssf = context.getServerSocketFactory();
SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(990);
ss.setSoTimeout(2000);
SSLSocket s = (SSLSocket)ss.accept();
ISR = new InputStreamReader(s.getInputStream());
OSW = new OutputStreamWriter(s.getOutputStream());
ClientSocketReader = new BufferedReader(ISR);
ClientSocketWriter = new PrintWriter(OSW, true);
ClientSocketWriter.println("234 AUTH TLS successful");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("331 Password required for smie");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("230 User smie logged in");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("215 UNIX Type: L8");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("550 Command not suported.");
}
}
catch(Exception e)
{
print(e);
}
Description: FTP client(for example MoveITFreely) connect to server on port 21. After send command "AUTH TLS", server send "234 AUTH TLS successful". Now client must to connect to server on port 990(?), but client dont connect and get timeout exception.
What i do wrong?
There exist two methods to add SSL to FTP.
First method is called implicit SSL. It means that the server is listening on port 990 and when the client connects to it, first SSL/TLS negotiation is performed, and then the established connection is used as a command channel for communication (for data channel SSL handshake is also performed in a similar manner).
Second method is what you attempt to use. It's called explicit SSL. The client connects on port 21, sends AUTH TLS and starts SSL negotiation on existing connection. Data channel can be secured or not secured depending on how you want it (you specify this using PROT command).
You mixed the methods. I suggest that you read detailed explanation in Wikipedia before going further. Then read RFC for explicit TLS.
Update: Also you'd need SSLClientSocket, not SSLServerSocket.