Я использую Java 6 и пытаюсь создать HttpsURLConnection
для удаленного сервера, используя сертификат клиента.
Сервер использует самоподписанный корневой сертификат и требует предоставления защищенного паролем клиентского сертификата. Я добавил корневой сертификат сервера и сертификат клиента в хранилище ключей Java по умолчанию, которое я нашел в /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts
(OSX 10.5).
Кажется, имя файла хранилища ключей указывает на то, что сертификат клиента не должен туда входить?
В любом случае, добавление корневого сертификата в этот магазин решило печально известную javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.
Однако я застрял на том, как использовать сертификат клиента. Я попробовал два подхода, и ни один из них никуда меня не привел.
Сначала, желательно, попробуйте:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://somehost.dk:3049");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
// The last line fails, and gives:
// javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Я попытался пропустить класс HttpsURLConnection (не идеально, так как я хочу общаться HTTP с сервером), и вместо этого сделать это:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("somehost.dk", 3049);
InputStream inputstream = sslsocket.getInputStream();
// do anything with the inputstream results in:
// java.net.SocketTimeoutException: Read timed out
Я даже не уверен, что проблема в сертификате клиента.