- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在本地测试客户端和服务器之间的 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/
我正在尝试关注 this tutorial .我想我不是从使用可下载项目开始,而是从我之前做过的一个简单的“spring MVC - Maven - eclipse”项目开始。这个项目运行良好。 因此
我觉得 Java EE 6 规范有些困惑。有几组注释。 我们有javax.ejb注释如 @Stateful和 @Stateless用于创建 EJB。 还有一个@javax.annotation.Man
我正在开发一个依赖于“javax.lang”和“javax.annotation”的java项目。我安装了jre/jdk,类路径上还有很多其他javax.*,我每天都用Java进行开发。但是,这两个包
我正在尝试将一个值添加到 JsonValue 列表中。可以这样做吗? 一些背景知识,我正在从 Rest API 检索 Json 响应,在此 Json 中是一个如下名称列表: { “名称”:{名称1,名
我正在开发一个 JSF2、Icefaces 网络应用程序。我有以下看法: 当我保存上面的 时出现以下异常. Application caught instance of
我遇到了一个小问题,我的代码中有一个异常。 我有一个基本框架类: import java.awt.BorderLayout; import java.awt.Color; import java.aw
我正在使用 Apache Derby 并具有以下代码: DBConnectionFactory.java package edu.unsw.comp9321.jdbc; import java.sql
javax.mail 和 javax.mail-api 有什么区别? 我从 maven 存储库中找到了那些。 什么时候应该使用它们? javax.mail-api自带的软件包,但我无法使用,所以我下载
我是 Java 的新手,正在尝试进入 WebServices。我在某处找到了两个示例,但对可用选项感到困惑。 首先,带注解的javax.jws.WebService 似乎工作正常,但javax.xml
在升级了一些 Glassfish/Grizzly 依赖项之后(为了与最新版本的 Azure SDK IOT 设备客户端兼容),我开始出现错误,因为 com.google.common.EventBus
我收到了一个遗留 JSP 系统,其中 Eclipse 在每次出现以下代码时都会标记“导入 javax.event 无法解析”错误: 这是我的java版本: shakir@anduril:~$ jav
我使用以下代码获取连接到系统的 USB 设备的制造商代码。我添加了 jsr80-1.0.1 jar 。我收到以下错误 javax.usb.UsbException: Properties file j
我正在学习 EJB,当尝试使用 junit 测试它时,出现以下错误 cd.espoirmur.Ejb.InterfaceEjbLocal_80488159 Jun 03, 2016 10:33:58
我必须处理一个需要提供数据源作为参数的 API。问题是我从提供 EntityManager 或 PersistentContext 的上下文访问它,它们似乎没有通过其方法公开任何数据源。如何以编程方式
据我所知,Java ServletContext 和上下文对象在 Java EE 程序开发中很常见。但是,我不太确定它们之间有什么区别,尤其是上下文类的用法。 据我了解,ServletContext
我在一个简单的 tomcat jsp 项目中遇到了这个错误。我在谷歌上阅读的文章暗示我应该在我的项目中包含 servlet-api.jar。我就是这样做的,但没有用。有人对此有任何想法吗?我的 JRE
我想对我的实体进行一些 Bean 验证,以便我可以适本地映射错误以发送回客户端。 我知道 javax.validation.constraints 注释用于实现此目的。我的问题是,对于模式生成,我需要
想法:2018.3 jetty :9.4.11 我按照 IDEA 中给出的说明下载了 jrebel 文件夹 在 Debug模式下运行 Jetty 服务器时出现以下错误。 HTTP ERROR 500
我正在开发一个主要使用无状态 session bean (SLSB) 的 EJB3 应用程序。他们使用容器管理事务 (CMT)。 我希望 bean 知道事务(用于日志记录等)。我可以实现 javax.
我正在使用 OSGI 开发 Web 应用程序。我有一个我找不到的 Maven 配置错误。这是完整的源代码: http://uploading.com/files/8e5c9888/SH_27_test
我是一名优秀的程序员,十分优秀!