首先创建服务器端私有密钥和公共密钥
1, keytool -genkey -alias serverkey -keystore kserver.ks
密码: serverpass
2, keytool -export -alias serverkey -keystore kserver.ks -file server.crt
3, keytool -import -alias serverkey -file server.crt -keystore tclient.ks
密码: clientpublicpass
下面创建客户器端私有密钥和公共密钥
1, keytool -genkey -alias clientkey -keystore kclient.ks
密码: clientpass
2, keytool -export -alias clientkey -keystore kclient.ks -file client.crt
3, keytool -import -alias clientkey -file client.crt -keystore tserver.ks
密码: serverpublicpass
把服务器端产生的公共密钥放到客户端, 同样把客户端创建的公共密钥放到服务器端.
下面是服务器端代码:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;
public class SSLTestServer {
public static void main(String[] args) throws Exception {
SSLContext ctx = SSLContext.getInstance("SSL");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore tks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("cert/kserver.ks"), "serverpass".toCharArray());
tks.load(new FileInputStream("cert/tserver.ks"), "serverpublicpass".toCharArray());
kmf.init(ks, "serverpass".toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLServerSocket serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(8443);
serverSocket.setNeedClientAuth(true);
while (true) {
try {
Socket s = serverSocket.accept();
InputStream input = s.getInputStream();
OutputStream utput = s.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(input);
BufferedOutputStream bos = new BufferedOutputStream(output);
byte[] buffer = new byte[20];
int length = bis.read(buffer);
System.out.println("Receive: " + new String(buffer, 0, length).toString());
bos.write("Hello".getBytes());
bos.flush();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
}
下面是客户端代码:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
public class SSLTestClient {
public static void main(String[] args) throws Exception {
SSLContext ctx = SSLContext.getInstance("SSL");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore tks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("cert/kclient.ks"), "clientpass".toCharArray());
tks.load(new FileInputStream("cert/tclient.ks"), "clientpublicpass".toCharArray());
kmf.init(ks, "clientpass".toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocket sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket("localhost", 8443);
InputStream input = sslSocket.getInputStream();
OutputStream utput = sslSocket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(input);
BufferedOutputStream bos = new BufferedOutputStream(output);
bos.write("Hello".getBytes());
bos.flush();
byte[] buffer = new byte[20];
int length = bis.read(buffer);
System.out.println(new String(buffer, 0, length));
sslSocket.close();
}
}
常见的HTTPS传输, 不需要进行客户端认证, 也就是单向认证. 这时也就不需要创建客户端的私钥和公钥. 服务器端也只要配置一下服务器端的私钥即可, 当客户端浏览器访问时会生成一个证书文件,类似于上面创建的crt文件. 如果需要程序访问,可以通过这个crt文件生成一个keystore. 然后是用这个keystore作为trust keystore即可.
目前我用keytool.exe生成的keystore和证书用于双向认证是没有问题的,但是使用ejbca系统生成的由某CA机构颁发的证书以及生成的keystore用来做双向认证就会报错。
javax.net.ssl.SSLHandshakeException: null cert chain
这个问题还需要进一步跟踪解决。
SSLSocket实现服务端和客户端双向认证的例子的更多相关文章
-
openssl实现双向认证教程(服务端代码+客户端代码+证书生成)
一.背景说明 1.1 面临问题 最近一份产品检测报告建议使用基于pki的认证方式,由于产品已实现https,商量之下认为其意思是使用双向认证以处理中间人形式攻击. <信息安全工程>中接触过 ...
-
C#在服务端验证客户端证书(Certificate)
使用https协议进行通讯的时候可以设置双向证书认证,客户端验证服务端证书的方法前面已经介绍过了,现在说一下在服务端验证客户端证书的方案. 这里给出的方案比较简单,只需要在Service端的配置文件中 ...
-
(转)SVN 服务端、客户端安装及配置、导入导出项目
SVN服务器搭建和使用(一) Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上 ...
-
使用flask_socketio实现服务端向客户端定时推送
websocket连接是客户端与服务器之间永久的双向通信通道,直到某方断开连接. 双向通道意味着在连接时,服务端随时可以发送消息给客户端,反之亦然,这在一些需要即时通讯的场景比如多人聊天室非常重要. ...
-
常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
-
红帽学习笔记[RHCE]OpenLDAP 服务端与客户端配置
目录 OpenLDAP 服务端与客户端配置 关于LDIF 一个LDIF基本结构一个条目 属性 Object的类型 服务端 安装 生成证书 生成默认数据 修改基本的配置 导入基础数据 关于ldif的格式 ...
-
eureka服务端和客户端的简单搭建
本篇博客简单记录一下,eureka 服务端和 客户端的简单搭建. 目标: 1.完成单机 eureka server 和 eureka client 的搭建. 2.完成eureka server 的添加 ...
-
asp.net获取服务端和客户端信息
asp.net获取服务端和客户端信息 获取服务器名:Page.Server.ManchineName获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostNam ...
-
python thrift 服务端与客户端使用
一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...
随机推荐
-
angular评论星级指令
地址: https://github.com/happen-zh/myStar 支持最大数,是否必填,回调,是否只读
-
cni 添加网络 流程分析
cnitool: Add or remove network interfaces from a network namespace cnitool add <net> <netns ...
-
【jacob word】使用jacob,合并多个word为一个word文件
将几个word文件合并到一个word文件,使用注意点: 1.后面附项目运用的jar包jacob-1.9, 2.并且jacob运用中,需要将附件内的jacob.dll放到windows/system32 ...
-
C语言-删除重复字符
//实现对一个字符串的删除重复的字符,并输出删除后的字符串,(如从”testroadeasy”中输出”tesroady”) Action(){ char *str="testroade ...
-
Java-马士兵设计模式学习笔记-责任链模式-FilterChain功能
一.目标 增加filterchain功能 二.代码 1.Filter.java public interface Filter { public String doFilter(String str) ...
-
sqlserver 增加用户并分配权限
1.创建用户cmd2:CREATE LOGIN cmd2 WITH PASSWORD='123qwe!@#',DEFAULT_DATABASE=DEV_CMD CREATE USER cmd2 FO ...
-
GDAL库中WFS服务中含有中文不能获取数据的问题
GDAL库中目前提供了对WFS服务发布的数据进行获取,目前发现对于中文的服务名称或者图层名为中文,GDAL不能正确识别.通过调试发现,其原因有下面两点: 1.输入的URL路径没有使用UTF8编码而从网 ...
-
Linux设备驱动之IIO子系统——IIO框架及IIO数据结构
由于需要对ADC进行驱动设计,因此学习了一下Linux驱动的IIO子系统.本文翻译自<Linux Device Drivers Development >--John Madieu,本人水 ...
-
Electron桌面应用打包流程
一. 准备工作 1.npm的安装需要下载node.js,安装完node.js之后npm自然会有. 参考链接:http://www.runoob.com/nodejs/nodejs-install-se ...
-
Shell命令-文件及目录操作之touch、tree
文件及目录操作 - touch.tree 1.touch:创建文件或更改文件时间戳 touch命令的功能说明 touch命令用于创建新的空文件或改变已有文件的时间戳属性. touch命令的语法格式 t ...