Настройка HTTPS на Tomcat и тестовый HTTPS клиент
Продолжаю небольшую серию постов про использование SSL. Сегодня я хочу завершить эксперимент с двусторонней аутентификацией, который не удалось реализовать на встроенном в JDK сервере. Я попробую настроить Tomcat и протестировать с ним одностороннюю и двустороннюю аутентификацию.
Поиски а интернете дали следующие результаты:
- Страничка на StackOverflow с примером конфигурации Tomcat для SSL http://stackoverflow.com/questions/5162279/configure-tomcat-to-use-a-trust-store-other-than-cacerts
- Tomcat SSL HowTo http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html#Configuration
- Документация на теги конфигурационного файла Tomcat http://tomcat.apache.org/tomcat-6.0-doc/config/http.html#SSL_Support
Вкратце, получается следующее. Tomcat поддерживает 2 типа SSL соединений: на основе OpenSSL и на основе стандартной Java реализации. Чтобы сконфигурировать HTTPS нужно минимально раскомментировать в файле conf/server.xml соответствующий коннектор, добавив в него ссылку на keystore файл и пароль к keystore файлу. В моем случае, я хочу протестировать двустороннюю аутентификацию. Для этого нужно еще добавить trustStore-файл, для хранения клиентского trusted сертификата и указать атрибут clientAuth=»true».
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="C:\java\apache-tomcat-6.0.29\conf\tomcat.jks" keystorePass="tomcat"
truststoreFile="C:\java\apache-tomcat-6.0.29\conf\tomcattrust.jks" truststorePass="tomcat"
clientAuth="true" sslProtocol="TLS" />
Генерирую tomcat.jks с помощью keytool:
keytool -genkey -dname "cn=tomcat,ou=dev64,o=dev64-wordpress,L=unspec, st=unspec, c=RU"
-alias tomcat -keypass tomcat -keystore tomcat.jks -storepass tomcat
Получаю файл с ключом и сертификатом сервера. Экспортирую сертификат сервера, чтобы подложить его в truststore моего тестового клиента:
keytool -export -keystore tomcat.jks -alias tomcat -storepass tomcat -file tomcat.cer
Получаю файл с сертификатом tomcat.cer. Импортирую сертификат сервера в truststore моего тестового клиента:
keytool -import -keystore clienttrust.jks -alias tomcat -file tomcat.cer -storepass storepass
Последним шагом, беру сертификат клиента и на его основе создаю tomcattrust.jsk — truststore для Tomcat:
keytool -import -keystore tomcattrust.jks -file client.cer -storepass tomcat
Беру свой тестовый код из предыдущего поста и тестирую.
@Test
public void testTwoWayAuthentication()
throws CertificateException, InterruptedException, UnrecoverableKeyException, NoSuchAlgorithmException,
IOException, KeyManagementException, KeyStoreException {
URL url = new URL("https://localhost:8443/");
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setRequestMethod( "GET" );
SSLContext sslContext = SSLContext.getInstance("TLS");
char[] passphrase = "storepass".toCharArray();
char[] keypass = "serverpass".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(SimpleServerTest.class.getResourceAsStream("client.jks"), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keypass);
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(this.getClass().getResourceAsStream("clienttrust.jks"), passphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return s.equals(sslSession.getPeerHost());
}
};
con.setHostnameVerifier(hostnameVerifier);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
con.setSSLSocketFactory(sslContext.getSocketFactory());
int responseCode = con.getResponseCode();
InputStream inputStream;
if (responseCode == HttpURLConnection.HTTP_OK) {
inputStream = con.getInputStream();
} else {
inputStream = con.getErrorStream();
}
// Process the response
BufferedReader reader;
String line = null;
reader = new BufferedReader( new InputStreamReader( inputStream ) );
while( ( line = reader.readLine() ) != null )
{
System.out.println( line );
}
inputStream.close();
}
Получаю адекватный ответ от сервера. Тест проходит. Если убрать двустороннюю аутентификацию в конфиге Tomcat, т.е. clientAuth=»false», тогда коннект проходит из браузера.
Т.о. все тесты с односторонней и двусторонней аутентификацией прошли и на этом я, пока, тему HTTPS завершаю.
Взято:
https://dev64.wordpress.com/2013/06/19/configure-https-at-apache-tomcat-and-https-test-client/