`
xiangqian0505
  • 浏览: 322276 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java实现 SSL双向认证

    博客分类:
  • java
 
阅读更多

我们常见的SSL验证较多的只是验证我们的服务器是否是真实正确的,当然如果你访问的URL压根就错了,那谁也没有办法。这个就是所谓的SSL单向认证。

 

但是实际中,我们有可能还会验证客户端是否符合要求,也就是给我们每个用户颁发一个证书,比且每个数字证书都是唯一的,不公开的。这样就能通过这个数字证书保证当前访问我服务器的这个用户是经过服务器认可的,其他人不可访问。

 

双向认证 从第一个层面上 确保了服务器 与客户端 都是互相认可的。那么他们之间要进行通信,就会在通信协议上附加SSL协议,确保通信的内容是加密的,即使是sniffer这样的网络嗅探工具看到的都是乱码。以后给大家演示下不加密的情况下,用sniffer看到的是什么。恐怕这样你就能提高警惕了。

 

以下内容从网络上摘抄 加以实际验证后修改的。

 

模拟场景:
Server
端和Client端通信,需要进行授权和身份的验证,即Client只能接受Server的消息,Server只能接受Client的消息。

实现技术:
JSSE
Java Security Socket Extension
Sun为了解决在Internet上的安全通讯而推出的解决方案。它实现了SSLTSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,开发人员可以在客户机和服务器之间通过TCP/IP协议安全地传输数据。

 

为了实现消息认证。
Server
需要:
1
KeyStore: 其中保存服务端的私钥
2
Trust KeyStore:其中保存客户端的授权证书
同样,Client需要:
1
KeyStore:其中保存客户端的私钥
2
Trust KeyStore:其中保存服务端的授权证书

 

在这里我还是推荐使用Java自带的keytool命令,去生成这样信息文件。当然目前非常流行的开源的生成SSL证书的还有OpenSSLOpenSSLC语言编写,跨系统。但是我们可能在以后的过程中用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通信程序来验证我们生成的证书是否可用。

客户端:

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);
        }
    }

}

 

服务器端:

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实现SSL双向认证的方法

    实现Java SSL双向认证通常涉及以下几个步骤: 1. **生成密钥库(KeyStore)**: - 服务器端需要一个KeyStore,存储其私钥,通常使用`keytool`命令生成,例如:`keytool -genkey -alias serverkey -keystore ...

    SSL双向认证java实现

    SSL 双向认证 Java 实现 SSL 双向认证是指在客户端和服务器端之间的通信过程中,双方都需要对对方进行身份验证和授权,以确保通信的安全性。Java 语言提供了 JSSE(Java Security Socket Extension)来实现 SSL ...

    Java ssl socket 双向认证

    在这个场景中,我们讨论的是如何在Java中设置和实现SSL套接字的双向认证。双向认证通常在高安全性环境中使用,例如银行、政府机构或企业内部网络,因为它们需要确保通信双方都是可信的。 首先,为了实现双向认证,...

    客户端与服务器SSL双向认证(客户端:java-服务端:java)

    下面将详细介绍Java实现SSL双向认证的步骤、关键概念和技术要点。 1. **生成证书**: - 服务器证书:首先,你需要为服务器生成一个自我签名的证书,这可以通过Java的keytool工具完成。创建一个Key Pair(公钥和...

    JAVA实现的SSL/TLS双向认证源代码

    本篇将深入探讨如何使用Java实现SSL/TLS双向认证,以及涉及到的相关工具和步骤。 首先,让我们理解什么是SSL/TLS双向认证。通常,SSL/TLS连接采用单向认证,即服务器验证客户端的身份,而客户端不需要验证服务器。...

    java实现_SSL双向认证.doc

    java实现_SSL双向认证,里面详细介绍怎样实现,还包括完整的实现代码,直接可用

    java实现-SSL双向认证1.docx

    在实现Java SSL双向认证的过程中,主要涉及到以下几个关键概念: 1. **KeyStore**:KeyStore是Java中存储密钥和证书的容器,对于服务器端,KeyStore保存着服务器的私钥和证书;对于客户端,KeyStore则保存着客户端...

    tomcat实现SSL双向认证

    Tomcat 实现 SSL 双向认证 Tomcat 是一个流行的开源 Web 应用服务器,而 SSL(Secure Sockets Layer)是一种常用的安全协议,用于确保 Web 应用程序之间的数据传输安全。本文将详细介绍如何在 Tomcat 中实现 SSL ...

    activemq ssl双向认证连接

    在这个场景中,我们将深入探讨如何在Java工程中使用ActiveMQ实现SSL双向认证连接。 首先,让我们了解SSL双向认证的基本概念。在传统的SSL单向认证中,客户端只需要验证服务器的身份,而服务器无需验证客户端。而在...

    netty的SSL双向认证

    在Netty中实现SSL双向认证,我们需要以下步骤: 1. **生成证书**:首先,为服务器和客户端分别生成数字证书。这通常包括创建私钥和公钥,然后使用证书签名请求(CSR)将公钥提交给受信任的证书颁发机构(CA)进行...

    SSL双向认证证书制作过程流程

    SSL双向认证证书制作过程主要涉及网络安全领域,尤其是用于保护网络通信的安全套接层(SSL)和传输层安全(TLS)协议。这些协议确保了数据在互联网上传输时的加密和完整性,防止中间人攻击和数据泄露。以下是SSL双向...

    ssl_java.zip

    在Java中实现SSL双向认证,也被称为mutual authentication,是指客户端和服务器都需要向对方证明自己的身份。以下将详细讲解这个过程及其相关的Java SSL包使用。 首先,了解SSL的工作流程。SSL握手过程通常包括以下...

    JAVA实现SSL协议

    **三、SSL双向认证** 双向认证(Mutual Authentication)在SSL中,不仅服务器需要向客户端证明其身份,客户端也需要向服务器证明自己的身份。这通常涉及以下步骤: 1. 客户端发送随机数和其他相关信息给服务器。 2. ...

    android访问自签CA的Https SSL双向认证(j2SE也能使用)

    本篇文章将深入探讨如何在Android应用中实现对自签CA的HTTPS SSL双向认证,并且这些实现方法同样适用于Java SE(J2SE)环境。 首先,我们需要了解HTTPS的基本原理。HTTPS是HTTP协议的安全版本,它通过SSL/TLS协议来...

    Java环境中配置SSL双向认证.doc

    Java环境中配置SSL双向认证是一项确保网络通信安全的重要技术,尤其在处理敏感数据传输时更为关键。SSL(Secure Sockets Layer)是一种网络安全协议,用于在互联网上建立加密连接,确保数据在传输过程中不被窃取或...

    GMSSL双向认证分析.docx

    双向认证是GMSSL的一个重要特性,它确保了通信双方的身份都能被正确验证,增强了网络通信的安全性。 在TLS协议中,双向认证主要通过TLS握手协议进行。这个过程分为客户端和服务器端交互的多个步骤: 1. **Client ...

    SSL 双向认证的配置总结

    以下是对SSL双向认证的详细配置进行的总结。 **一、SSL简介** SSL是为网络通信提供安全及数据完整性的一种安全协议,通过加密传输数据,防止中间人攻击和窃听。其升级版TLS(Transport Layer Security)在当前的...

    AndroidHttpClient访问Tomcat双向SSL验证服务器.pdf

    - 更多关于Java实现SSL双向认证的信息可参考:“java实现SSL双向认证”。 3. **OpenSSL命令行测试**: - 使用`OpenSSL`命令行工具直接连接到`Tomcat`服务器,以测试SSL双向验证过程。 ```bash openssl s_client...

    ssl双向认证密钥

    在SSL双向认证中,不仅服务器需要验证客户端的身份,客户端也需要验证服务器的身份,从而提供了更高级别的安全保护。这种模式通常在银行、企业内部网络或高度敏感的信息交换中使用。 在SSL双向认证中,涉及的主要...

    java实现https的双向认证源代码加doc详细说明

    是Sun为了解决在Internet上的实现...它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,可以在Client和Server之间通过TCP/IP协议安全地传输数据

Global site tag (gtag.js) - Google Analytics