- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java实现SSL双向认证的方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了Java实现SSL双向认证的方法。分享给大家供大家参考,具体如下:
我们常见的SSL验证较多的只是验证我们的服务器是否是真实正确的,当然如果你访问的URL压根就错了,那谁也没有办法。这个就是所谓的SSL单向认证.
但是实际中,我们有可能还会验证客户端是否符合要求,也就是给我们每个用户颁发一个证书,比且每个数字证书都是唯一的,不公开的。这样就能通过这个数字证书保证当前访问我服务器的这个用户是经过服务器认可的,其他人不可访问.
双向认证 从第一个层面上 确保了服务器 与客户端 都是互相认可的。那么他们之间要进行通信,就会在通信协议上附加SSL协议,确保通信的内容是加密的,即使是sniffer这样的网络嗅探工具看到的都是乱码。以后给大家演示下不加密的情况下,用sniffer看到的是什么。恐怕这样你就能提高警惕了.
以下内容从网络上摘抄 加以实际验证后修改的.
模拟场景:
Server端和Client端通信,需要进行授权和身份的验证,即Client只能接受Server的消息,Server只能接受Client的消息.
实现技术:
JSSE(Java Security Socket Extension) 。
是Sun为了解决在Internet上的安全通讯而推出的解决方案。它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,开发人员可以在客户机和服务器之间通过TCP/IP协议安全地传输数据.
为了实现消息认证.
Server需要:
1)KeyStore: 其中保存服务端的私钥 2)Trust KeyStore:其中保存客户端的授权证书 。
同样,Client需要:
1)KeyStore:其中保存客户端的私钥 2)Trust KeyStore:其中保存服务端的授权证书 在这里我还是推荐使用Java自带的keytool命令,去生成这样信息文件。当然目前非常流行的开源的生成SSL证书的还有OpenSSL。OpenSSL用C语言编写,跨系统。但是我们可能在以后的过程中用java程序生成证书的方便性考虑,还是用JDK自带的keytool.
1)生成服务端私钥,并且导入到服务端KeyStore文件中 。
keytool -genkey -alias serverkey -keystore kserver.keystore 过程中,分别需要填写,根据需求自己设置就行 。
keystore密码:123456 名字和姓氏:jin 组织单位名称:none 组织名称:none 城市或区域名称:BJ 州或省份名称:BJ 国家代码:CN 。
serverkey私钥的密码,不填写和keystore的密码一致。这里千万注意,直接回车就行了,不用修改密码。否则在后面的程序中以及无法直接应用这个私钥,会报错.
就可以生成kserver.keystore文件 。
server.keystore是给服务端用的,其中保存着自己的私钥 。
2)根据私钥,导出服务端证书 。
keytool -export -alias serverkey -keystore kserver.keystore -file server.crt server.crt就是服务端的证书 。
3)将服务端证书,导入到客户端的Trust KeyStore中 。
keytool -import -alias serverkey -file server.crt -keystore tclient.keystore tclient.keystore是给客户端用的,其中保存着受信任的证书 。
采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore中 。
1)keytool -genkey -alias clientkey -keystore kclient.keystore 2)keytool -export -alias clientkey -keystore kclient.keystore -file client.crt 3)keytool -import -alias clientkey -file client.crt -keystore tserver.keystore 。
如此一来,生成的文件分成两组 。
服务端保存:kserver.keystore tserver.keystore 客户端保存:kclient.keystore tclient.kyestore 。
以下是通过Java Socket通信程序来验证我们生成的证书是否可用.
客户端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
package
examples.ssl;
import
java.io.BufferedInputStream;
import
java.io.BufferedOutputStream;
import
java.io.FileInputStream;
import
java.io.IOException;
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;
/**
* SSL Client
*
*/
public
class
SSLClient {
private
static
final
String DEFAULT_HOST =
"127.0.0.1"
;
private
static
final
int
DEFAULT_PORT =
7777
;
private
static
final
String CLIENT_KEY_STORE_PASSWORD =
"123456"
;
private
static
final
String CLIENT_TRUST_KEY_STORE_PASSWORD =
"123456"
;
private
SSLSocket sslSocket;
/**
* 启动客户端程序
*
* @param args
*/
public
static
void
main(String[] args) {
SSLClient client =
new
SSLClient();
client.init();
client.process();
}
/**
* 通过ssl socket与服务端进行连接,并且发送一个消息
*/
public
void
process() {
if
(sslSocket ==
null
) {
System.out.println(
"ERROR"
);
return
;
}
try
{
InputStream input = sslSocket.getInputStream();
OutputStream output = sslSocket.getOutputStream();
BufferedInputStream bis =
new
BufferedInputStream(input);
BufferedOutputStream bos =
new
BufferedOutputStream(output);
bos.write(
"Client Message"
.getBytes());
bos.flush();
byte
[] buffer =
new
byte
[
20
];
bis.read(buffer);
System.out.println(
new
String(buffer));
sslSocket.close();
}
catch
(IOException e) {
System.out.println(e);
}
}
/**
* <ul>
* <li>ssl连接的重点:</li>
* <li>初始化SSLSocket</li>
* <li>导入客户端私钥KeyStore,导入客户端受信任的KeyStore(服务端的证书)</li>
* </ul>
*/
public
void
init() {
try
{
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(
"E://kclient.keystore"
), CLIENT_KEY_STORE_PASSWORD.toCharArray());
tks.load(
new
FileInputStream(
"E://tclient.keystore"
), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
null
);
sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);
}
catch
(Exception e) {
System.out.println(e);
}
}
}
|
服务器端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
package
examples.ssl;
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;
/***********************************************************************************************************************
* <ul>
* <li>1)生成服务端私钥</li>
* <li>keytool -genkey -alias serverkey -keystore kserver.keystore</li>
* <li>2)根据私钥,到处服务端证书</li>
* <li>keytool -exoport -alias serverkey -keystore kserver.keystore -file server.crt</li>
* <li>3)把证书加入到客户端受信任的keystore中</li>
* <li>keytool -import -alias serverkey -file server.crt -keystore tclient.keystore</li>
* </ul>
**********************************************************************************************************************/
/**
* SSL Server
*
*/
public
class
SSLServer {
private
static
final
int
DEFAULT_PORT =
7777
;
private
static
final
String SERVER_KEY_STORE_PASSWORD =
"123456"
;
private
static
final
String SERVER_TRUST_KEY_STORE_PASSWORD =
"123456"
;
private
SSLServerSocket serverSocket;
/**
* 启动程序
*
* @param args
*/
public
static
void
main(String[] args) {
SSLServer server =
new
SSLServer();
server.init();
server.start();
}
/**
* <ul>
* <li>听SSL Server Socket</li>
* <li> 由于该程序不是演示Socket监听,所以简单采用单线程形式,并且仅仅接受客户端的消息,并且返回客户端指定消息</li>
* </ul>
*/
public
void
start() {
if
(serverSocket ==
null
) {
System.out.println(
"ERROR"
);
return
;
}
while
(
true
) {
try
{
Socket s = serverSocket.accept();
InputStream input = s.getInputStream();
OutputStream output = s.getOutputStream();
BufferedInputStream bis =
new
BufferedInputStream(input);
BufferedOutputStream bos =
new
BufferedOutputStream(output);
byte
[] buffer =
new
byte
[
20
];
bis.read(buffer);
System.out.println(
new
String(buffer));
bos.write(
"Server Echo"
.getBytes());
bos.flush();
s.close();
}
catch
(Exception e) {
System.out.println(e);
}
}
}
/**
* <ul>
* <li>ssl连接的重点:</li>
* <li>初始化SSLServerSocket</li>
* <li>导入服务端私钥KeyStore,导入服务端受信任的KeyStore(客户端的证书)</li>
* </ul>
*/
public
void
init() {
try
{
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(
"E://kserver.keystore"
), SERVER_KEY_STORE_PASSWORD.toCharArray());
tks.load(
new
FileInputStream(
"E://tserver.keystore"
), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
null
);
serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);
serverSocket.setNeedClientAuth(
true
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
希望本文所述对大家java程序设计有所帮助.
最后此篇关于Java实现SSL双向认证的方法的文章就讲到这里了,如果你想了解更多关于Java实现SSL双向认证的方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有 2 个类:User 和 UserPicture,它们具有 1:1 关系。 public class User { @Id @GeneratedValue(strategy=G
使用ssh转发时,我无法针对远程服务器使用cvs和ftp进行提交。是否可以让服务器对我的机器发起请求-我希望服务器上的Web应用程序调用我的机器上的REST方法。 谢谢。 尼古拉·G。 最佳答案 是的
我正在 Python 2.7.12 中实现双向 A* 算法,并在 Russell 和 Norvig 第 3 章的罗马尼亚 map 上进行测试。边具有权重,目的是找到两个节点之间的最短路径。 这是测试图
您能否建议一种映射或类似的数据结构,让我们可以轻松地相互获取值和键。也就是说,每个都可以用来寻找另一个。 最佳答案 Java 在其标准库中没有双向映射。 例如使用 BiMap 来自Google Gua
我想同步两个数据库运行时 服务器 A:安装了公共(public) IP 和 mysql 的 Amazon ec2。服务器B:这是局域网中带有mysql的私有(private)机器。 (IP是私有(pr
保存双向@OneToOne 映射时,hibernate 是否应该在两个表上都记录? 我有一个包含 applicant_id 列的表 interview,它引用了包含字段 interview_id 的
我喜欢新的 SwipeRefreshLayout!它看起来很棒,而且非常容易使用。但我想在两个方向上使用它。我有一个消息屏幕,我想通过从上到下滑动来加载旧消息,我想通过从下到上滑动来加载新消息。 这个
使用 ICS 4.0.1(愿意升级到 4.0.3)(不会 root 和重写 android 操作系统) 在接收到 android beam 后,是否可以将 NDEF 消息发送回 android 手机
我想知道处理这种 git 场景的最佳方法: Git 仓库:CoreProduct Git repo b: SpecificCustomerProduct 是从 a fork 出来的 到目前为止,我们一
这个问题在这里已经有了答案: How to implement an efficient bidirectional hash table? (8 个回答) 关闭2年前。 我在 python 中做这个
您能否推荐一种 map 或类似的数据结构,我们可以在其中轻松地从彼此获取值和键。也就是说,每个都可以用来寻找另一个。 最佳答案 Java 在其标准库中没有双向映射。 例如使用 BiMap 来自 Goo
Java中是否有类似双面列表的东西?也许第三方实现? 这里有一个小例子来证明我的想法。 原始状态: 答:0-1-2-3 | | | | 乙:0-1-2-3 删除 B 中的元素 1 后: 空值 | 答:
我有两个实体通过这样的双向 OneToOne 关联连接: @Entity class Parent { @NotNull String businessKey; @OneToO
我已将 Vagrant 配置为使用 Rsync 共享文件夹而不是(非常慢)vboxsf VirtualBox 默认提供的文件系统: Vagrant.configure("2") do |config|
@keyframes mgm { from { max-height: 250px; } to { max-height: 0px; } } .mgm {
我想了解有关使用双向 LSTM 进行序列分类时合并模式的更多详细信息,尤其是对于我还不清楚的“Concat”合并模式。 根据我对这个方案的理解: 在将前向和后向层的合并结果传递到 sigmoid 函数
我有兴趣将本地 git 存储库设置为远程存储库的镜像。我已经阅读了一些可能相关的帖子,但主要区别在于我需要对两个存储库进行读写访问。 大多数时候,用户会针对 Repo A 工作,但是有时他们会针对 R
我已经仔细阅读了文档 https://firebase.google.com/docs/database/web/read-and-write以及网上很多例子。但这里有一个脱节:在将对象添加到数据库时
这个问题已经有答案了: Hibernate bidirectional @ManyToOne, updating the not owning side not working (3 个回答) 已关闭
我知道有很多关于它的问题,但我找不到针对我的问题的好的答案。 我使用 Jboss 作为 7,Spring 和 Hibernate (4) 作为 JPA 2.0 提供程序,因此我有简单的 @OneToM
我是一名优秀的程序员,十分优秀!