CA相互認証の完全な実装手順(付属のJavaクライアントコード)

まず、基本的な概念

注:プロの観点に加えて、以下の概念は、両方の個人的な理解は、権限を持っていません。

1.セキュリティ管理システムとは何ですか

公共システムに配置され、通常、一定の安全管理を必要とする、私の知る限り理解し、セキュリティ管理は三つの側面に分かれている場合:
まず、このようなアプリケーションの特定のユーザ名、パスワード、およびようになどのアプリケーション内のアクセス制御;
秒様々なパケットの暗号化および復号化プログラムとしてのデータ送信中にアプリケーションのセキュリティ、;
第三は、データ送信の前に通信のセキュリティメカニズムであり、双方が信頼できる信頼性の高い通信を確保するため、PKIは、一つの解決策です。

2. PKIとは何ですか

公開鍵インフラストラクチャPKIはどの手段、その公開鍵インフラストラクチャ、短いです。
公開鍵インフラストラクチャは、公開鍵暗号化とデジタル署名サービスシステムやプラットフォームを提供することであり、鍵と証明書を管理するように設計されています。信頼された証明書とキーを介して2つの側面かどうかを確認するためにコミュニケーション。

3. CAは何ですか

CA認証局は、証明書は、PKIの中核である権威を発行することを、短いです。
通常言えば、CAは、CA証明書がお金を必要とするために権威機関です。
CA証明書を使用したいが、また、HTTPSサイトを使用したくないかもしれません。しかし、時には、あなたは自分の証明書を生成する必要があるかもしれませんが、この証明書は、ブラウザがこのために舞台裏で、この文書では、安全でない、具体的なステップと考えられています。

4. HTTPSとは何ですか

HTTPSはHTTP転送プロセスデータの整合性と信頼性の機密性を確保するために、セキュアな伝送の採用プロトコルのHTTP通信でHTTP + SSL、人気の点で、SSL証明書が必要。

5、一方向認証

ネットワーク通信は双方向ではなく、常に双方向の安全認証です。片道されている可能性があり、唯一のほとんどのクライアント側の検証サービスに関係なく、クライアントの、信頼性があり、サーバが信頼性があります。そのようなサーバ証明書、サーバはクライアント証明書を必要としないこと、ブラウザの検証として、クライアント、。

6、双方向認証

クライアントがサーバの信頼性を確認する必要があること一方向認証に関して相互認証、サーバーは、必ずクライアントが信頼されていることを確認する必要があります。双方は、互いの証明書を確認する必要があります。

第二に、実装手順

1、環境

全体の研究プロセス技術の仮想マシンに加えて、物理マシンの方法を使用して、自分のコンピュータ上にある:
物理マシン:win8 +すなわち
仮想マシン:redhat6.4 + nginxの+ Tomcatの+のopenssl

2、nginxのインストール

2.1、インストールパッケージの準備

nginxのインストールは、他の構成要素の数、インターネットに依存して、以下の三つに頼る必要があると述べました。

opensslの
PCRE
のzlib

しかし、実際のインストール・プロセスは、OpenSSLのみが必要であることが判明し、他の2つは除外することができるので、2つのインストールパッケージの実際のインストールをダウンロードしてください:

nginxの-1.12.2.tar.gz
のopenssl-1.0.0a.tar.gz

2.2、OpenSSLをインストール

2.2.1、解凍

タール-zxvfのopenssl-1.0.0a.tar.gz

2.2.2設定

解凍ディレクトリを入力した後

。/構成、設定

2.2.3コンパイラ

メイク

2.2.4インストール

make installを

2.3、nginxのインストール

2.3.1、解凍

タール-zxvf nginxの-1.12.2.tar.gz

2.3.2設定

解凍は、ここで注意することは、フォルダ構成にファイルパラメータの除外がPCREということで、zlibのインストールディレクトリを指定して、インストールのSSLモジュールを指定したOpenSSL

./configureを--without-http_rewrite_module --without-http_gzip_module --with-http_ssl_module --with-opensslの= /ホーム/ tuzongxun / opensslの/ opensslの-1.0.0a

2.3.3コンパイラ

メイク

2.3.4インストール

make installを

あなたは、ディレクトリnginxのことnginxのインストールディレクトリよりも多くのインストールは/ usr / localディレクトリが表示されます

3、証明書の生成

3.1、ルート証明書の生成

預金のディレクトリは、mkdir SSL証明書を作成します。
ストアディレクトリにcdしたSSL証明書
opensslのgenrsa -out ca.key 2048ルート秘密鍵を生成し、

ここに画像を挿入説明
生産されたルート証明書

opensslのREQ -new -x509 -days 3650 -key ca.key -out ca.crt

ここに画像を挿入説明

3.2、サーバ証明書の生成

サーバーの秘密鍵への氏

opensslのgenrsa -out server.pem 1024
opensslのRSA -in server.pem -out server.keyの

ここに画像を挿入説明
要求発生、共通名がアクセスするドメイン名が必要であるところに注意を払う、と他のコンテンツに署名と同様のルート証明書を埋めることができ
ここに画像を挿入説明
発行要求のと、サーバ秘密鍵生成サーバ証明書を

opensslのX509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -outをserver.crt

ここに画像を挿入説明

4、一方向認証

CAウェイ認証は、サーバのみが信頼できることを確認する必要があり、そのための手順上記の、唯一のルート証明書を生成することが必要とされており、サーバ証明書があることができ、その後、あなたはnginxのを設定することができます。

4.1、nginxの設定

进入nginx的安装目录找到nginx.conf文件更改配置
ここに画像を挿入説明
主要是更改server里的内容,更改后如下:
ここに画像を挿入説明
主要更改如下:
默认的 listen 80为 listen 443 ssl;
server_name指向之前生成服务端证书时指向的域名blog.tzx.com;
使用 ssl on开启ssl安全认证功能;
ssl_certificate指定服务端证书的地址,如/usr/local/nginx/ssl/server.crt;
ssl_certificate_key指定服务端私钥地址,如/usr/local/nginx/ssl/server.key;
ssl_session_timeout设置ssl session超时时间5m;
更改默认的跟访问路径/的路由为实际需要访问的资源,例如这里指向了tomcat默认端口(启动了tomcat才能访问,或者其他具有8080端口的可访问资源)。
原本根目录配置如下,现在注释掉:

# location / {
#     root   html;
#     index  index.html index.htm;
# }

修改之后配置如下:

location / {
        proxy_pass   http://172.23.130.205:8080/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
        proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
 }

4.2、启动nginx

在nginx的sbin目录中启动nginx
ここに画像を挿入説明

4.3、修改客户端hosts文件,进行域名映射

由于上边的blog.tzx.com为自己虚拟的一个域名,所以电脑是不认识的,需要在客户端进行映射。
例如我这里要在自己的windows的ie浏览器中访问https://blog.tzx.com,就需要修改windows的hosts文件,C:\Windows\System32\drivers\etc\hosts,在文件中添加如下一行:

172.23.130.205 blog.tzx.com

这里blog.tzx.com为虚拟域名,前边的ip是nginx所在linux虚拟机的ip,意思是在这个windows机器中访问blog.tzx.com时,实际要访问172.23.130.205机器。

4.4、客户端安装根证书

上边启动nginx,并配置hosts之后,ie浏览器中就可以访问https://blog.tzx.com了,但是会提示不安全的站点,点击之后才能继续访问:
ここに画像を挿入説明
点击继续访问之后如下:
ここに画像を挿入説明
成功打开tomcat默认访问页面,但是url栏会提示证书错误,这是因为客户端根本无法判断服务端证书的正确性,没有依据,所以需要在浏览器安装根证书。
以ie为例,步骤依次是:
设置——》internet 选项——》内容——》证书
ここに画像を挿入説明
点击证书之后选择“受信任的根证书颁发机构”——》”导入”——》“下一步”——》“浏览”,然后选择根证书进行安装,这里的根证书即在linux中生成的ca.crt,需要先从linux中下载过来。
安装完成之后看到我们自己的CA机构信息:
ここに画像を挿入説明
清楚ie缓存,重新启动ie之后,再访问https://blog.tzx.com会看到可以直接访问了,并且没有了证书错误的提示,单向认证完毕:
ここに画像を挿入説明

5、双向认证

单向认证是客户端根据ca根证书验证服务端提供的服务端证书和私钥;双向认证还要服务端根据ca根证书验证客户端证书和私钥,因此双向认证之前还需要生成客户端证书和私钥。

5.1、生成客户端证书

客户端证书生成步骤和服务端基本一样,需要注意的就是在生成签发请求的时候填写的信息中,comm name也要是访问的域名,其他信息最好是和服务端的不一样。
ここに画像を挿入説明
客户端证书比服务端稍微多一步的就是,需要对客户端证书和私钥进行打包处理,这里方便安装以后后续访问时候携带,一般都是使用pkcs12进行打包:

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

打包时需要输入证书密码
ここに画像を挿入説明

5.2、nginx配置

双向认证,需要在nginx中开启服务端对客户端的认证,需要在server里加入如下的配置:

ssl_client_certificate /usr/local/nginx/ssl/ca.crt; 

指定客户端认证时使用的根证书路径,用来验证客户端证书的正确性,作用应该等同上边浏览器安装的根证书;

ssl_verify_client on;开启客户端认证。

ここに画像を挿入説明
重启nginx,目前我的nginx没有安装成服务,因此是先kill进程,再启动。

5.3、客户端认证

上边的步骤之后,再次到ie中访问https://blog.tzx.com无法访问,结果如下:
ここに画像を挿入説明
原因就是nginx已经开启了客户端CA认证,但是这一次的访问没有携带客户端证书等信息。
解决办法就是在ie中安装之前打包的pkcs12个人证书和秘钥,之后访问的时候可以选择携带这个证书及秘钥,就可以认证通过。
安装类似之前的ca根证书安装:
设置——》internet 选项——》内容——》证书,然后选择个人中的导入,输入密码后进行安装:
ここに画像を挿入説明
证书安装完成后,再次清楚ie缓存,然后重启浏览器访问,会看到如下弹窗:
ここに画像を挿入説明
点击确定后,浏览器就会发送这个证书给nginx服务端,然后正常显示tomcat界面:
ここに画像を挿入説明

至此,整个CA双向认证过程实现完毕。

5.4、java客户端认证

以java程序作为客户端,原理是一样的,也需要客户端请求时携带客户端证书和秘钥,并且客户端需要保存根证书,用来验证服务端证书的可靠性,所以首先需要安装根证书。

5.4.1、根证书安装

根证书可以使用jdk的keytool工具安装,方式有很多种,这里只选用库文件的模式。
首先,把根证书ca.crt复制一份,重命名为ca.cer,然后把这个文件复制到jdk的jre\lib\security目录下,在这个目录中进行根证书的安装:

keytool -keystore test.truststore -keypass 131112 -storepass 131112 -alias DemoCA -import -trustcacerts -file ca.cer

其中,test.truststore可以自定义名称,密码自定义,DemoCA别名自定义,ca.cer即刚才复制过来的文件,最后需要输入一个y确认信任。
ここに画像を挿入説明
如上图,便代表安装成功,这个证书就会被jdk信任。(理论上说,也可使用代码调用keytool安装证书)

5.4.2、java客户端代码

以下代码来自网络:https://www.cnblogs.com/dreamingodd/p/7491098.html

@Service
public class SSLService {
    // 客户端证书路径,用了本地绝对路径,需要修改
    private final static String CLIENT_CERT_FILE = "C:\\Users\\tzx\\Desktop\\client.p12";
    // 客户端证书密码
    private final static String CLIENT_PWD = "131112";
    // 信任库路径,即keytool生成的那个自定义名称的库文件
    private final static String TRUST_STRORE_FILE = "D:\\Java\\jdk1.8.0_131\\jre\\lib\\security\\test.truststore";
    // 信任库密码,即keytool时的密码
    private final static String TRUST_STORE_PWD = "131112";
    private static String readResponseBody(InputStream inputStream) throws IOException {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            StringBuffer sb = new StringBuffer();
            String buff = null;
            while ((buff = br.readLine()) != null) {
                sb.append(buff + "\n");
            }
            return sb.toString();
        } finally {
            inputStream.close();
        }
    }
    public static void httpsCall() throws Exception {
        // 初始化密钥库
        KeyManagerFactory keyManagerFactory = KeyManagerFactory
                .getInstance("SunX509");
        KeyStore keyStore = getKeyStore(CLIENT_CERT_FILE, CLIENT_PWD, "PKCS12");
        keyManagerFactory.init(keyStore, CLIENT_PWD.toCharArray());
        // 初始化信任库
        TrustManagerFactory trustManagerFactory = TrustManagerFactory
                .getInstance("SunX509");
        KeyStore trustkeyStore = getKeyStore(TRUST_STRORE_FILE, TRUST_STORE_PWD, "JKS");
        trustManagerFactory.init(trustkeyStore);
        // 初始化SSL上下文
        SSLContext ctx = SSLContext.getInstance("SSL");
        ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
                .getTrustManagers(), null);
        SSLSocketFactory sf = ctx.getSocketFactory();
        HttpsURLConnection.setDefaultSSLSocketFactory(sf);
        String url = "https://blog.tzx.com";
        URL urlObj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) urlObj.openConnection();
        con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 " +
                "(KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
        con.setRequestProperty("Accept-Language", "zh-CN;en-US,en;q=0.5");
        con.setRequestMethod("GET");
        String res = readResponseBody(con.getInputStream());
        System.out.println(res);
    }
    /**
     * 获得KeyStore
     */
    private static KeyStore getKeyStore(String keyStorePath, String password, String type)
            throws Exception {
        FileInputStream is = new FileInputStream(keyStorePath);
        キーストアKS = KeyStore.getInstance(タイプ)。
        ks.load(ある、password.toCharArray())。
        近くにあります();
        KSを返します。
    }
   公共の静的な無効メイン(文字列[] argsが){例外をスロー
    httpsCall(NULL)。
  }
}

トップを実行しているの主な方法は、あなたがホームページのhtmlコードTomcatの列歌手プリントアウトを見ることができます。
ここに画像を挿入説明
著作権:宝鶏でコーティングされました

公開された272元の記事 ウォンの賞賛371 ビュー126万+

おすすめ

転載: blog.csdn.net/tuzongxun/article/details/88647172