- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用自签名证书进行 SSL 双向身份验证。我为 client(client-keystore.jks) 和 server(server-keystore.jks) 创建了两个 keystore ,从两个 keystore 导出证书并将客户端证书导入到服务器 keystore 和服务器证书到客户端 keystore 。并更新了 server.xml 中所需的连接器条目,将两个证书添加到 java 信任库 cacerts。
Java 客户端代码:
KeyStore trustStore = KeyStore.getInstance("JKS", "SUN");
trustStore.load(SSLImplemetation.class.getResourceAsStream("C:/Program Files/Java/jdk1.7.0_79/jre/lib/security/cacerts"), "changeit".toCharArray());
String alg = KeyManagerFactory.getDefaultAlgorithm();
TrustManagerFactory fac = TrustManagerFactory.getInstance(alg);
fac.init(trustStore);
KeyStore keystore = KeyStore.getInstance("JKS", "SUN");
keystore.load(SSLImplemetation.class.getResourceAsStream("<dir path>/client-keystore.jks"), "test".toCharArra());
String keyAlg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory keyFac = KeyManagerFactory.getInstance(keyAlg);
keyFac.init(keystore, "test".toCharArray());
SSLContext ctx = SSLContext.getInstance("TLS", "SunJSSE");
ctx.init(keyFac.getKeyManagers(),fac.getTrustManagers(), new SecureRandom());
SslContextedSecureProtocolSocketFactory secureProtocolSocketFactory = new SslContextedSecureProtocolSocketFactory(ctx);
Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) secureProtocolSocketFactory, 8443));
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpPost request = new HttpPost("<rest service url>");
JSONObject obj = new JSONObject();
StringEntity params =new StringEntity(obj.toString());
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
System.out.println(response.getStatusLine());
服务器.xml:
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="<dir path>/server-keystore.jks" keystorePass="test"
truststoreFile="C:/Program Files/Java/jdk1.7.0_79/jre/lib/security/cacerts"
truststorePass="changeit" />
我是 SSl 的新手,所以有点困惑。任何帮助将不胜感激。
最佳答案
下面的代码对我来说工作正常,在创建两个客户端和服务器 keystore 并将证书都放入 java truststore 之后,我使用下面的代码进行 SSL 相互身份验证。
static final private String KEY_STORE = "D:/sslcertificates/client-keystore.jks";
static final private String KEY_STORE_TYPE = "JKS";
static final private String KEY_STORE_PASS = "test";
public static void main(String[] args) throws JSONException{
try {
URL url = new URL("<rest service url>");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("<hostname>")) {
return true;
}
return false;
}
});
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
try
{
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509","SunJSSE");
KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE);
File cert = new File(KEY_STORE);
InputStream stream = new FileInputStream(cert);
ks.load(stream, KEY_STORE_PASS.toCharArray());
stream.close();
kmf.init(ks,KEY_STORE_PASS.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(),null, new SecureRandom());
SSLSocketFactory factory = context.getSocketFactory();
conn.setSSLSocketFactory(factory);
}
catch(Exception e)
{
System.out.println(e);
}
JSONObject obj = new JSONObject();
obj.put("id","abc");
obj.put("name","surya");
obj.put( "domain","IT");
String input=obj.toString();
//send request to server....
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
System.out.println("Response code: "+conn.getResponseCode());
System.out.println("Response message: "+conn.getResponseMessage());
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
服务器.xml
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="<dir path>/server-keystore.jks" keystorePass="test"/>
注意:在 HttpsURLConnection 对象中设置 HostnameVerifier,客户端和服务器 keystore 的 CN 应该是主机名。
如果有更好的解决方案,请提出建议。
关于java - 面对 javax.net.ssl.SSLHandshakeException : Received fatal alert: bad_certificate issue while implementing SSL two way authentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36760089/
我经常在 C 标准文档中看到“实现定义”的说法,并且非常将其作为答案。 然后我在 C99 标准中搜索它,并且: ISO/IEC 9899/1999 (C99) 中第 §3.12 条规定: 3.12 I
“依赖于实现”中的“实现”是什么意思? “依赖于实现”和“依赖于机器”之间有什么区别? 我使用C,所以你可以用C解释它。 最佳答案 当 C 标准讨论实现时,它指的是 C 语言的实现。因此,C 的实现就
我刚刚在 Android-studio 中导入了我的项目,并试图在其中创建一个新的 Activity。但我无法在 android-studio 中创建 Activity 。我指的是here我看不到将目
我想知道您对为什么会发生此错误的意见。在陆上生产环境中,我们使用 CDH4。在我们的本地测试环境中,我们只使用 Apache Hadoop v2.2.0。当我运行在 CDH4 上编译的同一个 jar
我正在尝试集成第三方 SDK (DeepAR)。但是当我构建它时,它会显示一个错误。我试图修复它。如果我创建一个简单的新项目,它就可以正常工作。但是我现有的应用程序我使用相机和 ndk。请帮我找出错误
我很好奇为什么我们有 @Overrides 注释,但接口(interface)没有类似的习惯用法(例如 @Implements 或 @Implementation)。这似乎是一个有用的功能,因为您可能
我对 DAODatabase(适用于 Oracle 11 xe)的 CRUD 方法的实现感到困惑。问题是,在通常存储到 Map 集合的情况下,“U”方法(更新)会插入新元素或更新它(像 ID:Abst
Java-API 告诉我特定类实现了哪些接口(interface)。但有两种不同类型的信息,我不太确定这意味着什么。例如,对于“TreeSet”类:https://docs.oracle.com/en
我有一个接口(interface) MLService,它具有与机器学习算法的训练和交叉验证相关的基本方法,我必须添加两个接口(interface)分类和预测,它们将实现 MLService 并包含根
我一直想知道如何最好地为所有实现相同接口(interface)的类系列实现 equals()(并且客户端应该只使用所述接口(interface)并且永远不知道实现类)。 我还没有编写自己的具体示例,但
我有一个接口(interface)及其 2 个或更多实现, public interface IProcessor { default void method1() { //logic
我有同一个应用程序的免费版和高级版(几乎相同的代码,相同的类,到处都是“if”, list 中的不同包, list 中的进程名称相同)。主要 Activity 使用 IMPLICIT Intent 调
这是我为我的应用程序中的错误部分编写的代码 - (id)initWithData:(NSData *)data <-------- options:(NSUInteger)opti
请查找随附的代码片段。我正在使用此代码将文件从 hdfs 下载到我的本地文件系统 - Configuration conf = new Configuration(); FileSys
我想在 MongoDB 中使用 Grails2.5 中的“ElasticSearch”插件。我的“BuildConfig.groovy”文件是: grails.servlet.version = "3
我收到一条错误消息: fatal error: init(coder:) has not been implemented 对于我的自定义 UITableViewCell。该单元格未注册,在 Stor
得到这个错误 kotlin.NotImplementedError: An operation is not implemented: not implemented 我正在实现一个 ImageBut
typedef int Element; typedef struct { Element *stack; int max_size; int top; } Stack; //
Playground 代码 here 例子: interface IFoo { bar: number; foo?: () => void; } abstract class Abst
我想知道如何抑制警告: Category is implementing a method which will also be implemented by its primary class. 我
我是一名优秀的程序员,十分优秀!