SSLSocket实现服务端和客户端双向认证的例子

首先创建服务器端私有密钥和公共密钥
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

这个问题还需要进一步跟踪解决。

时间: 2024-10-12 15:25:20

SSLSocket实现服务端和客户端双向认证的例子的相关文章

(转)SVN 服务端、客户端安装及配置、导入导出项目

SVN服务器搭建和使用(一) Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址: http://subversion.apache.org/packages.html 这是二进制文件包的下载地址,你可在左侧的导航栏找到源代码,文档的下载地址. windows操作系统下面的二进制文件包一共有5种,如图: 个人认为最好用VisualSVN server 服务端和 To

关于ntp(时间同步协议)服务端和客户端的配置说明

本文主要写了一些在Linux(CentOS)服务器上配置ntp的经验,事件缘由来源于配置Zabbix监控ntp服务时的测试配置. NTP时间同步协议的服务端(ntpd服务)和客户端(ntpdate服)不能同时运行,即在运行ntpd服务后不能运行ntpdate服务,否则ntpdate服务会提示启动失败,而且日志中也会提示"the NTP socket is in use, exiting",如下图所示. 但客户端运行时,服务端可以运行,但服务端运行时,客户端不能运行,要运行客户端服务,就

socket服务端和客户端

#!/usr/bin/env python#encoding: utf-8import socketdef handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") client.send("Hello, World") def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREA

用Java实现HTTP Multipart的服务端和客户端

今天简单介绍一下如何用Java支持HTTP Multipart的request和response. 整个项目的代码可以在https://github.com/mcai4gl2/multi下载. 在这个程序里,我们的业务场景很简单.在服务端有一个随机数生成器,可以生成随机的Integer和Guid,客户端通过服务,可以请求一个或多个随机数.同时,客户端可以向服务端发送一个或多个随机数,这些随机数会被加入到一个队列中,被其他的客户端通过请求获得.以下是我们的随机数Bean的定义: [java] vi

C# Socket服务端和客户端互相send和receive

服务端 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Net.Sockets; 5 using System.Net; 6 using System.Threading; 7  8 namespace Controller 9 {10     public static class SocketServer11     {12         private stat

CnetOS 6.6 rsync 的服务端和客户端配置

CentOS 6.6 rsync 的服务端和客户端配置 基本信息 系统版本 主机名 IP地址 角色 CentOS  6.6 backup 10.0.0.10 rsync服务端 CentOS  6.6 lamp01 10.0.0.8 rsync客户端 CentOS  6.6 lnmp02 10.0.0.9 rsync客户端 服务端配置 创建rsync配置文件,并写入配置内容(默认rsync文件是不存在的,需要创建) [[email protected] ~]# touch/etc/rsyncd.c

Java网络编程【Socket服务端和客户端】

Socket 编程大家都不陌生,Java 学习中必学的部分,也是 Java网络编程核心内容之一.Java 网络编程又包括 TCP.UDP,URL 等模块.TCP 对应 Socket模块,UDP 对应 DatagramPacket 模块.URL 对应 URL 模块.其中 TCP 和 UDP 是网络传输协议,TCP 是数据流传输协议,UDP 是数据包传输协议.两者之间的异同就不在这里说了,推荐一本入门书籍 <TCPIP入门经典>.我们开始 Socket 服务端和客户端编程吧. 一.Socket 服

SVN1.6服务端和客户端安装配置指导

本节向大家描述SVN1.6服务端和客户端安装配置步骤,随着SVN的快速发展,版本也进行了升级更新,本节就和大家一起学习一下SVN1.6服务端和客户端安装配置步骤,欢迎大家一起来学习.下面是具体介绍.1.软件下载下载SVN1.6服务器程序.http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91[注意]如果之前已经安装了TortoiseSVN客户端,必须选择与之配套的SVN服务端版本,否则会出现各种问题,可以从Tor

grpc(3):使用 golang 开发 grpc 服务端和客户端

1,关于grpc-go golang 可以可以做grpc的服务端和客户端. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://github.com/grpc/grpc-go 和之前写的java的grpc客户端调用相同.也需要使用protobuf的配置文件. 但是golang下面的类库非常的简单,而且golang的性能也很强悍呢. 有些简单的业务逻辑真的可以使用golang进行开发. 性能强悍而且,消耗的资源也很小.java感觉上已