gpt4 book ai didi

java - ReSTLet javax.net.ssl.SSLHandshakeException : null cert chain

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:52:37 24 4
gpt4 key购买 nike

我正在本地测试客户端和服务器之间的 SSL 通信。所以我使用 OpenSSL 命令生成了证书。在 cacert 文件中添加了此证书。还生成了 .p12 文件。

我在服务器和客户端使用相同的 .p12 文件。这是服务器代码

Server server = component.getServers().add(Protocol.HTTPS, port);
Series<Parameter> params = server.getContext().getParameters();

params.add("keystorePath", ".p12 file path");
params.add("keystoreType", "PKCS12");
params.add("needClientAuthentication","true");

component.getDefaultHost().attach("", "/AA"), new AAClass());
component.start();

这是客户端代码:

Client client = trustAllCerts();
clientResource = new ClientResource(url);
clientResource.setNext(client);
try{
clientText = clientResource.post"");
}
catch(ResourceException e){
e.printStackTrace();
}

public Client trustAllCerts() {
Client client = null;
try {
client = new Client(new Context(), Protocol.HTTPS);
Context context = client.getContext();


final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
context.getAttributes().put("sslContextFactory", new SslContextFactory() {
public void init(Series<Parameter> parameters) {

}

public SSLContext createSslContext() {
return sslContext;
}
});
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context.getAttributes().put("hostnameVerifier", new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}

});

sslContext.init(null, new TrustManager[] { tm }, null);

} catch (KeyManagementException e) {
LOGGER.error("Exception in Key Management" + e);
} catch (NoSuchAlgorithmException e) {
LOGGER.error("Exception in Algorithm Used" + e);
}
return client;
}

我遇到以下异常:

Restlet-1299242, fatal error: 42: null cert chain
javax.net.ssl.SSLHandshakeException: null cert chain
%% Invalidated: [Session-25, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
Restlet-1299242, SEND TLSv1.2 ALERT: fatal, description = bad_certificate
Restlet-1299242, WRITE: TLSv1.2 Alert, length = 2
Restlet-1299242, fatal: engine already closed. Rethrowing javax.net.ssl.SSLHandshakeException: null cert chain
Restlet-1299242, called closeInbound()
Restlet-1299242, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
Restlet-1299242, called closeOutbound()
Restlet-1299242, closeOutboundInternal()

我尝试使用 System.setProperty() 添加 keystore 和信任库,但没有成功。

请帮忙。提前致谢。

最佳答案

首先,让我们创建一个 JKS 格式的 keystore 。 PKCS12 通常在浏览器中使用,默认的 java 应用程序使用 JKS(据我所知)。 Java 也支持 PKCS12,但我不知道它的确切参数。

准备 JKS 文件

让我们查看我们的 PKCS12 文件并获取我们想要提取 JKS 文件的证书别名。

keytool -list \
-keystore [*.p12 file] \
-storepass [password] \
-storetype PKCS12 \
-v

记下您要导出的别名。现在让我们创建一个 JKS 文件。

keytool -keystore [*.jks file path] -genkey -alias client

这会问很多问题。你可以随意填充它们。现在,您可以将别名从 *.p12 文件导出到 *.jks 文件。

keytool -importkeystore \
-srckeystore [*.p12 file path] \
-srcstoretype pkcs12 \
-srcalias [alias from first command] \
-destkeystore [*.jks file path] \
-deststoretype jks \
-deststorepass [*.jks file password] \
-destalias [new alias]

如果您没有任何 PKCS12 文件,或者您的证书是 CER、DER 或 PEM 格式,您可以使用以下命令将您的证书添加到您的 keystore 。

keytool -import \
-alias [new alias] \
-keystore [*.jks file path] \
-file [*.DER file path]

请确保您导入了您的证书、您的证书提供商的证书(中间证书)和根证书。

现在您可以检查您的 JKS 文件是否包含您需要的所有证书。

keytool -list \
-keystore [*.jks file path] \
-storepass [password] \
-storetype jks \
-v

设置服务器

您可以在客户端和服务器端使用您的 JKS 文件。根据Restlet documentation您可以像这样使用 JKS 文件来提供 HTTPS 连接。

Server server = component.getServers().add(Protocol.HTTPS, port);  
Series<Parameter> parameters = server.getContext().getParameters();
parameters.add("sslContextFactory","org.restlet.engine.ssl.DefaultSslContextFactory");
parameters.add("keyStorePath", "*.jks file");
parameters.add("keyStorePassword", "password");
parameters.add("keyPassword", "password");
parameters.add("keyStoreType", "JKS");

之后,如果您从浏览器检查您的端口,您必须看到一个安全标志。或者您可以使用一些在线工具(like this one)来检查您的证书。

设置客户端

现在让我们看看客户端。由于您正在开发应用程序的两面,因此您可以使用已经创建的 JKS 文件。

Context con = new Context();
Series<Parameter> clParameters = con.getParameters();
clParameters.add("truststorePath", "*.jks file");
clParameters.add("truststorePassword", "password");
clParameters.add("truststoreType", "JKS");
Client restletClient = new Client(con, Protocol.HTTPS);

在测试或其他情况下,您的证书主机名和实际主机名可能不匹配。为了禁用主机名检查,您可以将此 block 添加到您的应用程序。

static{
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession ) {
return true ;
}
});
}

一些想法

由于我无法在我的语言环境中对其进行测试,我不确定您的客户端和服务器 JKS 文件是否必须相同。您可能只需要将自己的证书添加到您的 server.jks。 SSL 和证书对我来说总是很棘手。我通常会在反复试验后让它工作。希望对您有所帮助。

此外,您可能还需要考虑使用反向代理类型的 Web 服务器,例如 Apache2 或 Nginx。如果您想使用它们,您必须将您的证书合并到一个文件中。如果您查看您的证书文件,您会发现每个文件(您自己的证书、中间证书和根证书)都是这样的

-----BEGIN CERTIFICATE-----
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUA...
....
-----END CERTIFICATE-----

您只需将一个添加到另一个即可创建合并证书。而不是使用该证书在 Apache2 或 Nginx 上结束 SSL。这就是我通常做的。但是在客户端,您仍然需要创建 JKS 文件。

关于java - ReSTLet javax.net.ssl.SSLHandshakeException : null cert chain,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32506278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com