我正在使用Java 6,并尝试HttpsURLConnection
使用客户端证书针对远程服务器创建一个。
服务器正在使用自签名的根证书,并且要求提供受密码保护的客户端证书。我已将服务器根证书和客户端证书添加到在/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts(OSX 10.5)
中找到的默认Java密钥库中。密钥库文件的名称似乎表明不应将客户端证书放入其中?
无论如何,将根证书添加到此存储解决了臭名昭著的问题 html" target="_blank">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
我什至不确定客户端证书是否是这里的问题。
对我来说,这是使用Apache HttpComponents〜HttpClient 4.x的方法:
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("client-p12-keystore.p12"));
try {
keyStore.load(instream, "helloworld".toCharArray());
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, "helloworld".toCharArray())
//.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) //custom trust store
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); //TODO
CloseableHttpClient httpclient = HttpClients.custom()
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) //TODO
.setSSLSocketFactory(sslsf)
.build();
try {
HttpGet httpget = new HttpGet("https://localhost:8443/secure/index");
System.out.println("executing request" + httpget.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
EntityUtils.consume(entity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
P12文件包含使用BouncyCastle创建的客户端证书和客户端私钥:
public static byte[] convertPEMToPKCS12(final String keyFile, final String cerFile,
final String password)
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException,
NoSuchProviderException
{
// Get the private key
FileReader reader = new FileReader(keyFile);
PEMParser pem = new PEMParser(reader);
PEMKeyPair pemKeyPair = ((PEMKeyPair)pem.readObject());
JcaPEMKeyConverter jcaPEMKeyConverter = new JcaPEMKeyConverter().setProvider("BC");
KeyPair keyPair = jcaPEMKeyConverter.getKeyPair(pemKeyPair);
PrivateKey key = keyPair.getPrivate();
pem.close();
reader.close();
// Get the certificate
reader = new FileReader(cerFile);
pem = new PEMParser(reader);
X509CertificateHolder certHolder = (X509CertificateHolder) pem.readObject();
java.security.cert.Certificate x509Certificate =
new JcaX509CertificateConverter().setProvider("BC")
.getCertificate(certHolder);
pem.close();
reader.close();
// Put them into a PKCS12 keystore and write it to a byte[]
ByteArrayOutputStream bos = new ByteArrayOutputStream();
KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
ks.load(null);
ks.setKeyEntry("key-alias", (Key) key, password.toCharArray(),
new java.security.cert.Certificate[]{x509Certificate});
ks.store(bos, password.toCharArray());
bos.close();
return bos.toByteArray();
}
问题内容: 我还很陌生,对于使用证书进行身份验证时客户端应该显示的内容有些困惑。 我正在编写一个Java客户端,该客户端需要对POST特定对象进行简单的数据处理URL。那部分工作正常,唯一的问题是应该完成。该部分相当容易处理(无论是使用Java的内置HTTPS支持还是使用Java的内置支持),但是我一直坚持使用客户端证书进行身份验证。我注意到这里已经存在一个非常类似的问题,我还没有尝试使用我的代码
问题内容: 我正在尝试建立与trackobot.com的连接以接收一些JSON数据。服务器仅允许通过HTTPS / SSL进行连接。这是代码: openSteam抛出javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure 我通读了与类似问题有关的几篇文章,但没有任何建议可以帮助您。适当的证书在我的信任库中。例如,当我尝试连接到goo
使用java-version:1.8.0_171,我试图连接到API网关,但使用java8却得到一个SSL handshake_failure。已经运行的命令: 启用时,我得到了以下信息: 更新
问题内容: 我们的系统与多个Web服务提供商进行通信。它们都是从单个Java客户端应用程序调用的。到目前为止,所有的Web服务都已通过SSL进行,但是没有一个使用客户端证书。好吧,一个新的合作伙伴正在改变这一现状。 使应用程序使用证书进行调用很容易;设置和将做到这一点。但是,现在的问题是如何制作它,使其仅在调用该特定Web服务时使用证书。我想更一般地说,我们希望能够选择要使用的客户端证书(如果有)
我有一个小的springboot应用程序。我需要使用HTPPS,我从CA购买带有嵌入式tomcat的SSL证书。我试着配置它。应用财产: p、 12.使用keytool创建 **.我从加州得到的crt。我也有私钥,但不知道我需要在哪里使用它。 当我尝试启动此应用程序时,出现了一个错误 为什么应用程序看不到别名?我在keystore中看到了。 可能我需要一些其他设置来在springboot tomc
我遇到了使用客户端存根通过https发送soap请求的问题。我正在运行Ubuntu16并使用Eclipse。Ive使用KeyTool在中添加了证书。 如有任何帮助,我们将不胜感激。