Unrecognized SSL message, plaintext connection--SSLSocket 代理服務器連接


雖然java代碼  URL.openconnect(proxy);已經實現了https客戶端通過代理連接服務器

但個人在使用socket https代理http://www.cnblogs.com/hua198/p/5223945.html時一直出現一個問題Unrecognized SSL message, plaintext connection

大致意思是在SSL連接過程中收到不可以識別的消息

產生這個問題一般有兩種

1.發送了明文消息

2.SSL握手出現問題,不能正確完成握手

通過連接的代碼,使用代理后一直無法完成握手,原因還是與HTTPS代理連接出現問題,因為代碼直接與HTTPS服務器連接正常,握手報文順序是正常的

通過IE瀏覽器代理抓包分析,在SSL握手報文頭部出現了proxy-connect-name:xxx.yyy.com proxy-connect-port:443

然道是java在握手過程中加入這些數據,后來發現https使用代理連接過程中,客戶端向代理服務器發送一個connect xxx.yyy.com:443 HTTP/1.1的一個http的報文

顯然在ssl代理過程中,客戶端先要通過connect與代理服務器建立連接,ssl代理服務器需要與服務器完成ssl握手,建立連接。然后客戶端再與代理服務器建立ssl連接。


import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.SecureRandom;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class Ssl {


public static void sslSocket2() throws Exception {
SSLContext context = SSLContext.getInstance("SSL");
// 初始化
TrustManager[] tm = { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
} };

context.init(null, tm, new SecureRandom());
SSLSocketFactory factory = context.getSocketFactory();

//_____________________________________________________

Socket socket= new Socket("127.0.0.1",8080); //代理服務器
StringBuffer connect = new StringBuffer("CONNECT mail.163.com:443 HTTP/1.1\r\n\r\n");
OutputStream output1 = socket.getOutputStream();
output1.write(connect.toString().getBytes());
output1.flush();

InputStream input1 = socket.getInputStream();
byte[] buf1 = new byte[1024];
input1.read(buf1);
System.out.println(new String(buf1));

SSLSocket s = (SSLSocket) factory.createSocket(socket,"mail.163.com", 443,true);

//_____________________________________________________
// SSLSocket s = (SSLSocket) factory.createSocket("mail.163.com", 443);

// s.startHandshake();
OutputStream output = s.getOutputStream();
InputStream input = s.getInputStream();

output.write(("POST https://mail.163.com/entry/cgi/ntesdoor?df=mail163_letter&from=web&funcid=loginone&iframe=1&language=-1&passtype=1&product=mail163&net=t&style=-1&race=1139_1154_1123_bj&uid=xj-07@163.com HTTP/1.1"
+"\r\nAccept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*"
+"\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)"
+"\r\nContent-Type: application/x-www-form-urlencoded"
+"\r\nAccept-Encoding: gzip, deflate"
+"\r\nHost: mail.163.com"
+"\r\nContent-Length: 106" //body的字符個數
+"\r\nConnection: Keep-Alive"
+"\r\nCache-Control: no-cache"
+"\r\nReferer: http://mail.163.com/"
+"\r\nAccept-Language: zh-CN"+"\r\n"
+"\r\nsavelogin=0&url2=http%3A%2F%2Fmail.163.com%2Ferrorpage%2Ferror163.htm&username=xj-0701&password=xxx12345yy").getBytes());
output.flush();

byte[] buf = new byte[1024];
int len = input.read(buf);
System.out.println("received:" + new String(buf, 0, len));
}
public static void main(String[] args) throws Exception {

sslSocket2();
}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM