SSL soketli bir sunucuya bağlanmak için Java (Android) kullanmaya çalışıyorum. Lütfen bunun HTTP verisi olmadığını unutmayın. Bu, metin ve ikili veri karışımıyla özel protokoldür.SSL proxy'si bir HTTP proxy üzerinden nasıl bağlanır?
Bu SSL bağlantısını bir HTTP proxy üzerinden aktarmak istiyorum ancak bununla ilgili birçok sorunla karşılaşıyorum. Şu anda kullandığım ve tarayıcımın bir kalamar proxy'si ile kullanıldığı göründüğü senaryo şu
[istemci] -> [http bağlantı] -> [proxy] -> [ssl bağlantı] -> [sunucu]
Bu, tarayıcı için çalışır, çünkü vekil ssl bağlantısını yaptıktan sonra, hemen bir TLS anlaşması gerçekleşir. Ancak kodum bunu yapmıyor gibi görünüyor. Ben
final TrustManager[] trustManager = new TrustManager[] { new MyX509TrustManager() };
final SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustManager, null);
SSLSocketFactory factory = context.getSocketFactory();
Socket s = factory.createSocket(new Socket(proxy_ip, 3128), hostName, port, true);
sorun createSocket ASLA GERİ DÖNÜYOR olmasıdır. Proxy makineden bir wireshark dökümü ile, vekil sunucu ile sunucu arasında bir tcp el sıkışma olduğunu görebiliyorum. Web oturumlarındaki dökümlerle, müşterimin genellikle senaryoda gerçekleşmeyen bir SSL el sıkışma başlattığını görebiliyorum.
Bu sertifika yöneticisi ile ilgili bir sorun değildir çünkü sertifika asla bana geri dönmez ve hiçbir zaman doğrulanmaz.
DÜZENLEME:
tartışmalar sonrasında, bu şimdiye yönetmeye çalışıyorum kod daha tam sürümüdür. Yukarıdaki bu sürüm ile basit (yeni Soket (...)) parametresi daha sonra denediğim bir şeydir.
final Socket proxySocket = new Socket();
proxySocket.connect(proxyAddress, 2000); // 2 seconds as the connection timeout for connecting to the proxy server
[Start a thread and write to outputStream=socket.getOutputStream()]
final String proxyRequest = String.format("CONNECT %s:%d HTTP/1.1\r\nProxy-Connection: keep-alive\r\nConnection: keep-alive\r\nHost: %s:%d\r\n\r\n", hostName, port, hostName, port);
outputStream.close(); // Closing or not doesn't change anything
[Stop using that thread and let it exit by reaching the end of its main function]
Ardından aşağıdaki yanıtı okuyun:
Ben Hata ayıklamak çalışıyorum kod orijinal versiyonu dizisi (biraz tekrar basitleştirilmiş) şu şekilde olmaktadır
java.net.ConnectException: failed to connect to /192.168.1.100 (port 443): connect failed: ETIMEDOUT (Connection timed out)
atar kodu:
final InputStreamReader isr = new InputStreamReader(proxySocket.getInputStream());
final BufferedReader br = new BufferedReader(isr);
final String statusLine = br.readLine();
boolean proxyConnectSuccess = false;
// readLine consumed the CRLF
final Pattern statusLinePattern = Pattern.compile("^HTTP/\\d+\\.\\d+ (\\d\\d\\d) .*");
final Matcher statusLineMatcher = statusLinePattern.matcher(statusLine);
if (statusLineMatcher.matches())
{
final String statusCode = statusLineMatcher.group(1);
if (null != statusCode && 0 < statusCode.length() && '2' == statusCode.charAt(0))
{
proxyConnectSuccess = true;
}
}
// Consume rest of proxy response
String line;
while ("".equals((line = br.readLine())) == false)
{
}
Bu kodun SSL olmadan çalıştığından çalıştığını söyleyebilirim. Burada oluşturulan soket, proxySocket
, orijinal örneğimde olduğu gibi anında yeni bir tane oluşturmak yerine, createSocket işlevine iletilendir.
java.net.Proxy HTTP altında çalışmaz. SOCKS proxy gerektiriyor gibi görünüyor. Güneş os için bir yama buldum ama android için bir şey yok. Bu, Android'in üçüncü taraf uygulamaları olmadan HTTPS/SOCKS desteği sağlayamadığı için HTTP için çalışmasının çok önemlidir (varsayılan yükleme, Ocak 2015'te yeterli yapılandırma sağlamaz). – Eric
Bir HTTP proxy'si üzerinden bir SSL soketine bağlanıyorsanız, mümkün olan durumlarda websockets'ları düşünmenizi öneririz - özellikle "java.net.ConnectException: hata iletisi" /192.168.1.100 (bağlantı noktası 443) 'e bağlanamadığı için " standart HTTPS bağlantı noktasına bağlanmak için bir girişimi gösterir. Tabii ki, kullanım durumunuza bağlıdır .... –