Как использовать TLS 1.2 в Java 6
Кажется, что Java 6 поддерживает TLS до версии 1.0, есть ли способ использовать TLS 1.2 в Java 6?
Возможно, исправление или конкретное обновление Java 6 будет поддерживать его?
Ответы
Ответ 1
Публичные выпуски Oracle Java 6 не поддерживают TLSv1.2. Платные версии Java 6 (после EOL) могут. (UPDATE) TLSv1.1 доступен для Java 1.6 начиная с обновления 111, source)
Обратитесь к продажам Oracle.
Другие альтернативы:
Однако я бы посоветовал перейти на Java 8. Java 6 был EOL'd в феврале 2013 года, и продолжать использовать его потенциально рискованно. (Расскажите или напомните начальнику/клиенту. Они должны знать.)
Ответ 2
Здесь TLSConnection Factory:
package test.connection;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.security.cert.X509Certificate;
import org.bouncycastle.crypto.tls.Certificate;
import org.bouncycastle.crypto.tls.CertificateRequest;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.ExtensionType;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsCredentials;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* This Class enables TLS V1.2 connection based on BouncyCastle Providers.
* Just to use:
* URL myurl = new URL( "http:// ...URL tha only Works in TLS 1.2);
HttpsURLConnection con = (HttpsURLConnection )myurl.openConnection();
con.setSSLSocketFactory(new TSLSocketConnectionFactory());
* @author AZIMUTS
*
*/
public class TSLSocketConnectionFactory extends SSLSocketFactory {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Adding Custom BouncyCastleProvider
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
Security.addProvider(new BouncyCastleProvider());
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//HANDSHAKE LISTENER
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class TLSHandshakeListener implements HandshakeCompletedListener {
@Override
public void handshakeCompleted(HandshakeCompletedEvent event) {
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SECURE RANDOM
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
private SecureRandom _secureRandom = new SecureRandom();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Adding Custom BouncyCastleProvider
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public Socket createSocket(Socket socket, final String host, int port, boolean arg3)
throws IOException {
if (socket == null) {
socket = new Socket();
}
if (!socket.isConnected()) {
socket.connect(new InetSocketAddress(host, port));
}
final TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), _secureRandom);
return _createSSLSocket(host, tlsClientProtocol);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SOCKET FACTORY METHODS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public String[] getDefaultCipherSuites() {
return null;
}
@Override
public String[] getSupportedCipherSuites(){
return null;
}
@Override
public Socket createSocket(String host, int port) throws IOException,UnknownHostException{
return null;
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return null;
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost,
int localPort) throws IOException, UnknownHostException {
return null;
}
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddress, int localPort) throws IOException{
return null;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SOCKET CREATION
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private SSLSocket _createSSLSocket(final String host , final TlsClientProtocol tlsClientProtocol) {
return new SSLSocket() {
private java.security.cert.Certificate[] peertCerts;
@Override
public InputStream getInputStream() throws IOException {
return tlsClientProtocol.getInputStream();
}
@Override
public OutputStream getOutputStream() throws IOException {
return tlsClientProtocol.getOutputStream();
}
@Override
public synchronized void close() throws IOException {
tlsClientProtocol.close();
}
@Override
public void addHandshakeCompletedListener(HandshakeCompletedListener arg0) {
}
@Override
public boolean getEnableSessionCreation() {
return false;
}
@Override
public String[] getEnabledCipherSuites() {
return null;
}
@Override
public String[] getEnabledProtocols() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean getNeedClientAuth(){
return false;
}
@Override
public SSLSession getSession() {
return new SSLSession() {
@Override
public int getApplicationBufferSize() {
return 0;
}
@Override
public String getCipherSuite() {
throw new UnsupportedOperationException();
}
@Override
public long getCreationTime() {
throw new UnsupportedOperationException();
}
@Override
public byte[] getId() {
throw new UnsupportedOperationException();
}
@Override
public long getLastAccessedTime() {
throw new UnsupportedOperationException();
}
@Override
public java.security.cert.Certificate[] getLocalCertificates() {
throw new UnsupportedOperationException();
}
@Override
public Principal getLocalPrincipal() {
throw new UnsupportedOperationException();
}
@Override
public int getPacketBufferSize() {
throw new UnsupportedOperationException();
}
@Override
public X509Certificate[] getPeerCertificateChain()
throws SSLPeerUnverifiedException {
// TODO Auto-generated method stub
return null;
}
@Override
public java.security.cert.Certificate[] getPeerCertificates()throws SSLPeerUnverifiedException {
return peertCerts;
}
@Override
public String getPeerHost() {
throw new UnsupportedOperationException();
}
@Override
public int getPeerPort() {
return 0;
}
@Override
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
return null;
//throw new UnsupportedOperationException();
}
@Override
public String getProtocol() {
throw new UnsupportedOperationException();
}
@Override
public SSLSessionContext getSessionContext() {
throw new UnsupportedOperationException();
}
@Override
public Object getValue(String arg0) {
throw new UnsupportedOperationException();
}
@Override
public String[] getValueNames() {
throw new UnsupportedOperationException();
}
@Override
public void invalidate() {
throw new UnsupportedOperationException();
}
@Override
public boolean isValid() {
throw new UnsupportedOperationException();
}
@Override
public void putValue(String arg0, Object arg1) {
throw new UnsupportedOperationException();
}
@Override
public void removeValue(String arg0) {
throw new UnsupportedOperationException();
}
};
}
@Override
public String[] getSupportedProtocols() {
return null;
}
@Override
public boolean getUseClientMode() {
return false;
}
@Override
public boolean getWantClientAuth() {
return false;
}
@Override
public void removeHandshakeCompletedListener(HandshakeCompletedListener arg0) {
}
@Override
public void setEnableSessionCreation(boolean arg0) {
}
@Override
public void setEnabledCipherSuites(String[] arg0) {
}
@Override
public void setEnabledProtocols(String[] arg0) {
}
@Override
public void setNeedClientAuth(boolean arg0) {
}
@Override
public void setUseClientMode(boolean arg0) {
}
@Override
public void setWantClientAuth(boolean arg0) {
}
@Override
public String[] getSupportedCipherSuites() {
return null;
}
@Override
public void startHandshake() throws IOException {
tlsClientProtocol.connect(new DefaultTlsClient() {
@Override
public Hashtable<Integer, byte[]> getClientExtensions() throws IOException {
Hashtable<Integer, byte[]> clientExtensions = super.getClientExtensions();
if (clientExtensions == null) {
clientExtensions = new Hashtable<Integer, byte[]>();
}
//Add host_name
byte[] host_name = host.getBytes();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final DataOutputStream dos = new DataOutputStream(baos);
dos.writeShort(host_name.length + 3); // entry size
dos.writeByte(0); // name type = hostname
dos.writeShort(host_name.length);
dos.write(host_name);
dos.close();
clientExtensions.put(ExtensionType.server_name, baos.toByteArray());
return clientExtensions;
}
@Override
public TlsAuthentication getAuthentication()
throws IOException {
return new TlsAuthentication() {
@Override
public void notifyServerCertificate(Certificate serverCertificate) throws IOException {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<java.security.cert.Certificate> certs = new LinkedList<java.security.cert.Certificate>();
for ( org.bouncycastle.asn1.x509.Certificate c : serverCertificate.getCertificateList()) {
certs.add(cf.generateCertificate(new ByteArrayInputStream(c.getEncoded())));
}
peertCerts = certs.toArray(new java.security.cert.Certificate[0]);
} catch (CertificateException e) {
System.out.println( "Failed to cache server certs"+ e);
throw new IOException(e);
}
}
@Override
public TlsCredentials getClientCredentials(CertificateRequest arg0)
throws IOException {
return null;
}
};
}
});
}
};//Socket
}
}
Помните, что для доказательства этого лучше всего протестировать веб-сайт, который предоставляет ТОЛЬКО TLS 1.2. Если в Интернете предоставляется TLS 1.0, TLS 1.1 в зависимости от реализации Java будет подключаться с использованием tls 1.0, tls 1.1. Протестируйте его на сайте, который предоставляет только TLS 1.2. Примером может служить защищенный сайт NIST https://www.nist.gov
Ответ 3
Java 6, теперь поддерживающая TLS 1.2, выберете ниже
http://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_121
Ответ 4
Вы должны создать свой собственный SSLSocketFactory на основе Bouncy Castle. После его использования перейдите к общему HttpsConnextion для использования этого настроенного SocketFactory.
1. Сначала: создайте TLSConnectionFactory
Вот несколько советов:
1.1 Расширение SSLConnectionFactory
1.2 Переопределите этот метод:
@Override
public Socket createSocket(Socket socket, final String host, int port, boolean arg3)
Этот метод вызовет следующий внутренний метод,
1.3 Внедрить внутренний метод _createSSLSocket (host, tlsClientProtocol);
Здесь вы должны создать Socket, используя TlsClientProtocol. Уловка отменена... метод startHandshake(), вызывающий TlsClientProtocol
private SSLSocket _createSSLSocket(final String host , final TlsClientProtocol tlsClientProtocol) {
return new SSLSocket() {
.... Override and implement SSLSocket methods, particulary:
startHandshake() {
}
}
Важно: полный пример использования протокола TLS Client хорошо объясняется здесь: Использование BouncyCastle для простого HTTPS-запроса
2. Второй: используйте этот настраиваемый SSLConnextionFactory для общего HTTPSConnection.
Это важно! В других образцах, которые вы можете увидеть в Интернете, вы видите жестко закодированные HTTP-команды... так что с помощью настраиваемого SSLConnectionFactory вам больше ничего не нужно...
URL myurl = new URL( "http:// ...URL tha only Works in TLS 1.2);
HttpsURLConnection con = (HttpsURLConnection )myurl.openConnection();
con.setSSLSocketFactory(new TSLSocketConnectionFactory());
Ответ 5
В случае, если вам нужен доступ к определенному набору удаленных служб, вы можете использовать промежуточный обратный прокси-сервер, чтобы выполнить tls1.2 для вас. Это избавит вас от попыток исправления или обновления java1.6.
например
app → proxy: http (5500) [tls-1.2] → remote: https (443)
В простейшей форме (один порт на службу) для Apache httpd:
Listen 127.0.0.1:5000
<VirtualHost *:5500>
SSLProxyEngine On
ProxyPass / https://remote-domain/
ProxyPassReverse / https://remote-domain/
</VirtualHost>
Затем вместо доступа к https://remote-domain/ вы получаете доступ http://localhost:5500/
Ответ 6
Я думаю, что решение @Azimuts (fooobar.com/info/332603/...) только для HTTP-соединения.
Для соединения FTPS вы можете использовать Bouncy Castle с org.apache.commons.net.ftp.FTPSClient без необходимости переписывать протокол FTPS.
У меня есть программа, работающая на JRE 1.6.0_04, и я не могу обновить JRE.
Программа должна подключаться к серверу FTPS, который работает только с TLS 1.2 (сервер IIS).
Я боролся в течение нескольких дней, и, наконец, я понял, что в моем случае есть несколько версий библиотеки надувных замков: bctls-jdk15on-1.60.jar и bcprov-jdk15on-1.60.jar в порядке, но версии 1.64 - нет.
Ниже приведен небольшой фрагмент кода, который должен работать:
import java.io.ByteArrayOutputStream;
import java.security.SecureRandom;
import java.security.Security;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
import org.junit.Test;
public class FtpsTest {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { 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) {
}
} };
@Test public void test() throws Exception {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
Security.addProvider(new BouncyCastleJsseProvider());
SSLContext sslContext = SSLContext.getInstance("TLS", new BouncyCastleJsseProvider());
sslContext.init(null, trustAllCerts, new SecureRandom());
org.apache.commons.net.ftp.FTPSClient ftpClient = new FTPSClient(sslContext);
ByteArrayOutputStream out = null;
try {
ftpClient.connect("hostaname", 21);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
String msg = "Il server ftp ha rifiutato la connessione.";
throw new Exception(msg);
}
if (!ftpClient.login("username", "pwd")) {
String msg = "Il server ftp ha rifiutato il login con username: username e pwd: password .";
ftpClient.disconnect();
throw new Exception(msg);
}
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setDataTimeout(60000);
ftpClient.execPBSZ(0); // Set protection buffer size
ftpClient.execPROT("P"); // Set data channel protection to private
int bufSize = 1024 * 1024; // 1MB
ftpClient.setBufferSize(bufSize);
out = new ByteArrayOutputStream(bufSize);
ftpClient.retrieveFile("remoteFileName", out);
out.toByteArray();
}
finally {
if (out != null) {
out.close();
}
ftpClient.disconnect();
}
}
}