这样keytool就在当前目录下创建了三个授权文件然后我们将servercer文件导入到clientTrust文件中将alicecer和bobcer导入到serverTruest文件中
keytool import alias server keystore clientTrust file servercer
keytool import alias alice keystore serverTrust file alicecer
keytool import alias bob keystore serverTrust file bobcer
到目前为止在当前目录下包含clientKeysserverKeysclientTrustserverTrust四个文件完成了KeyStore和TrustStore的设置后就可以运行例子程序了首先需要运行服务器程序
java sslkeyStore=serverKeys
sslkeyStorePassword=password
ssltrustStore=serverTrust
ssltrustStorePassword=password SimpleSSLServer
在命令行中我们指定了keyStore属性为serverKeys由于服务器程序需要获得客户端的授权信息我们指定trustStore为serverTrust这样SSLSimpleServer就可以验证由SSLSimpleClient提供的授权信息当服务器程序成功运行后你会看到下面的提示
SimpleSSLServer running on port
这时候服务器会等待客户端发出建立连接的申请如果你希望在另一个端口上运行服务器程序可以在命令中指定port xxx参数其中xxx是端口号
然后在另一个命令窗口中运行客户端程序
java sslkeyStore=clientKeys
sslkeyStorePassword=password
ssltrustStore=clientTrust
ssltrustStorePassword=password SimpleSSLClient
客户端程序会试图向本机的端口建立SSL连接同样你可以通过port参数指定端口号也可以通过host参数指定主机名称当连接成功后会出现下面的提示信息
Connected
同时在服务器端会提示用户客户端已经连接成功
SimpleSSLServer
让我们先来看一下SimpleSSLServer在main()方法中程序获得了缺省的SSLServerSocketFactory对象然后利用SSLServerSocketFactory创建一个SimpleSSLServer对象最后调用start()方法启动SimpleSSLServer对象
SSLServerSocketFactory ssf=
(SSLServerSocketFactory)SSLServerSocketFactorygetDefault();
SimpleSSLServer server=new SimpleSSLServer(ssf port);
serverstart();
由于服务器是在一个单独的线程中运行的main()方法启动了服务器之后就退出了start()方法启动了一个新的线程该线程执行run()方法中的代码在run()方法中创建了一个SSLServerSocket对象然后设定服务器需要进行客户端验证
SSLServerSocket serverSocket= (SSLServerSocket)serverSocketFactorycreateServerSocket(port);
serverSocketsetNeedClientAuth(true);
调用run()方法后程序进入了一个死循环等待客户端的连接申请循环中的每个Socket对应一个HandshakeCompletedListener对象(该对象是用来显示客户验证信息中的标识名称[distinguished name]的)Socket的InputStream对象被包装在一个InputDisplayer对象中这个InputDisplayer对象运行在另外一个线程中用来将Socket接收到的数据发送到Systemout下面的代码是SimpleSSLServer中的主循环体
while (true) {
String ident=StringvalueOf(id++);
//监听连接请求
SSLSocket socket=(SSLSocket)serverSocketaccept();
//通过使用HandshakeCompletedListener对象程序进行授权验证
HandshakeCompletedListener hcl=new SimpleHandshakeListener(ident);
socketaddHandshakeCompletedListener(hcl);
InputStream in=socketgetInputStream();
new InputDisplayer(ident in);
}
程序中的SimpleHandshakeListener类实现了HandshakeCompletedListerner接口在SimpleHandshakeListener类中实现了handshakeCompleted()方法该方法在SSL握手阶段完成后将被JSSE调用它将显示出客户端的标识名称
class SimpleHandshakeListener implements HandshakeCompletedListener
{
String ident;
/**
* 构造函数
*/
public SimpleHandshakeListener(String ident)
{
thisident=ident;
}
/**当SSL握手过程完成后该方法被激活 */
public void handshakeCompleted(HandshakeCompletedEvent event)
{
//显示授权信息
try {
XCertificate
cert=(XCertificate)eventgetPeerCertificates()[];
String peer=certgetSubjectDN()getName();
Systemoutprintln(ident+: Request from +peer);
}
catch (SSLPeerUnverifiedException pue) {
Systemoutprintln(ident+: Peer