HTTPS双向认证配置

最近看了下HTTPS相关的,概念性的东西各位就去查查资料吧。主要找到两篇比较靠谱的文章,收藏下。

摘要: 概述: 客户端,浏览器或者使用http协议和服务器通信的程序。 如: 客户端通过浏览器访问某一网站时,如果该网站为HTTPS网站,浏览器会自动检测系统中是否存在该网站的信任证书, 如果没有信任证书,浏览器一般会拒绝访问,IE会有一个继续访问的链接,但地址栏是红色,给予用户警示作用, 即客户端验证服务端并不是强制性的,可以没有服务端的信任证书,当然是否继续访问完全取决于用户自己。 如果要去除地址栏的红色警告,需要导入服务端提供的证书到浏览器中。 服务器端,使用http协议提供服务的程序。 服务端需要获取到客户端通过浏览器发送过来的认证证书, 如: 该证书在服务端的证书库中已存在,仅仅是个...

概述:
客户端,浏览器或者使用http协议和服务器通信的程序。
如:
客户端通过浏览器访问某一网站时,如果该网站为HTTPS网站,浏览器会自动检测系统中是否存在该网站的信任证书,
如果没有信任证书,浏览器一般会拒绝访问,IE会有一个继续访问的链接,但地址栏是红色,给予用户警示作用,
即客户端验证服务端并不是强制性的,可以没有服务端的信任证书,当然是否继续访问完全取决于用户自己。
如果要去除地址栏的红色警告,需要导入服务端提供的证书到浏览器中。

服务器端,使用http协议提供服务的程序。
服务端需要获取到客户端通过浏览器发送过来的认证证书,
如:
该证书在服务端的证书库中已存在,仅仅是个匹配过程,匹配成功即通过认证,可继续访问网站资源,反之则无法显示网页。

基本逻辑:
1、生成服务端密钥库并导出证书.
2、生成客户端密钥库并导出证书.
3、根据服务端密钥库生成客户端信任的证书.
4、将客户端证书导入服务端密钥库.
5、将服务端证书导入浏览器.

源码下载地址:http://pan.baidu.com/s/1eQ5r9OA


生成密钥库和证书:
因使用java环境,下面使用jdk下面的keytool工具来生成相应的密钥库和证书
下面的命令是在windows 7 下面测试通过的,可以直接复制使用
1、创建目录,如d:/sslDemo

2、使用资源管理进入d:/sslDemo,按住shift+右键,弹出菜单,选择"在此处打开命令行".

3、服务器端相关操作
3.1、生成服务器证书库
keytool -validity 36500 -genkey -v -alias server -keyalg RSA -keystore server.keystore -dname "CN=www.itjoyee.com,OU=itjoyee.com,O=itjoyee.com,L=Wuhan,ST=HuBei,c=cn" -storepass 123456 -keypass 123456
注: 服务器证书库参数“CN”必须与服务端的IP地址相同,否则会报错,客户端的任意。

3.2、从服务器证书库中导出服务器证书
keytool -export -v -alias server -keystore server.keystore -storepass 123456 -rfc -file server.cer

3.3、生成客户端信任证书库(由服务端证书生成的证书库,客户端使用此证书验证服务端来源可靠)
keytool -import -v -alias server -file server.cer -keystore client.truststore -storepass 123456 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider

注:-storetype BKS 是生成android上面可以识别的格式,如果不指定jdk默认生成的格式是JKS.
-provider org.bouncycastle.jce.provider.BouncyCastleProvider,需要下载jar包bcprov-jdk16-1.46.jar放到jdk1.7.0_65\jre\lib\ext\目录下.
注意需要jdk16,其他的版本android下面有版本不匹配的问题.


4、客户端相关操作
4.1、生成客户端证书库
keytool -validity 36500 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore client.p12 -dname "CN=clients.itjoyee.com,OU=jiajianfa,O=jiajianfa,L=Wuhan,ST=HuBei,c=cn" -storepass 123456 -keypass 123456

4.2、从客户端证书库中导出客户端证书
keytool -export -v -alias client -keystore client.p12 -storetype PKCS12 -storepass 123456 -rfc -file client.cer

注:客户端证书可以产生多个.

4.3、将客户端证书导入到服务器证书库(使得服务器信任客户端证书,服务器端用此验证客户端的合法性)
keytool -import -v -alias client -file client.cer -keystore server.keystore -storepass 123456

4.4、查看服务端证书中信任的客户端证书
keytool -list -keystore server.keystore -storepass 123456

5、服务器端配置
由于使用tomcat,下面使用tomcat做为实例配置.
5.1、在tomcat安装目录下新建key目录,将上面生成的server.keystore复制过去.
5.2、编辑tomcat安装目录下的conf目录下的server.xml,如:d:\sslDemo\apache-tomcat-7.0.55\conf\server.xml
找到Connector,修改如下:

<Connector port="8444" protocol="org.apache.coyote.http11.Http11NioProtocol" 
           maxThreads="150" 
           SSLEnabled="true" scheme="https" secure="true"
           keystoreFile="${catalina.base}/key/server.keystore" keystorePass="123456"
           
           clientAuth="true" sslProtocol="TLS"
           truststoreFile="${catalina.base}/key/server.keystore" truststorePass="123456"/>

注:           
port配置https访问的端口
SSLEnabled="true" 开启https服务
scheme="https"
secure="true"    开启服务端安全通信,客户端获取服务器端证书
keystoreFile="${catalina.base}/key/server.keystore" keystorePass="123456" 服务器证书库

clientAuth="true" 开启验证客户端
sslProtocol="TLS" 使用的协议
truststoreFile="${catalina.base}/key/server.keystore" truststorePass="123456" 服务器证书库(已导入客户端证书)

6、测试
由于生成证书CN配置的是www.itjoyee.com,故需要修改C:\Windows\System32\drivers\etc\hosts
添加

192.168.0.50    www.itjoyee.com
注:
192.168.0.50 为服务器的ip

启动tomcat
打开浏览器
地址栏输入 http://www.itjoyee.com:8080/
可以访问

地址栏输入https://www.itjoyee.com:8444/
访问结果,为无法显示,因为,没有使服务器端生成的信任的客户端证书

双击client.p12,输入密码,在此访问https://www.itjoyee.com:8444/
此时会有证书相关的提示,点击"确认",接着会提示网站安全证书有问题,点击继续访问,即可进入正常访问页面

7、tomcat下的服务强制使用ssl配置
已ROOT服务为例,修改D:\sslDemo\apache-tomcat-7.0.55\webapps\ROOT\WEB-INF\web.xml
添加

<security-constraint>       
    <web-resource-collection>
        <web-resource-name >SSL</web-resource-name>  
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>  
    </user-data-constraint>
</security-constraint>

打开浏览器
地址栏输入 http://www.itjoyee.com:8080/会有证书相关提示


为了方便测试android下双向认证可以用,生成证书的时候把域名换成服务器的ip地址,验证才可以通过

1、android app 代码实现

AsyncTask testTask = new AsyncTask() {
            @Override
            protected Object doInBackground(Object... params) {
                try {
                    HttpClient httpsClient = AppSslApplication.getHttpsClient(MainActivity.this.getBaseContext());
                    HttpGet httpget = new HttpGet(HTTPS_URL);
                    HttpResponse response = httpsClient.execute(httpget);
                    HttpEntity entity = response.getEntity();
                    Log.e("Response status", response.getStatusLine().toString());
                    if (entity != null) {
                        Log.e("Response""Response content length: " + entity.getContentLength());
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
                        String text;
                        while ((text = bufferedReader.readLine()) != null) {
                            Log.e("Response status", text);
                        }
                        bufferedReader.close();
                    }
                    httpsClient.getConnectionManager().shutdown();
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        };
        testTask.execute();
public class HttpClientSslHelper {
    private static final String KEY_STORE_TYPE_BKS = "bks";
    private static final String KEY_STORE_TYPE_P12 = "PKCS12";
    private static final String SCHEME_HTTPS = "https";
    private static final int HTTPS_PORT = 8444;
    
    private static final String KEY_STORE_CLIENT_PATH = "client.p12";
    private static final String KEY_STORE_TRUST_PATH = "client.truststore";
    private static final String KEY_STORE_PASSWORD = "123456";
    private static final String KEY_STORE_TRUST_PASSWORD = "123456";
    private static KeyStore keyStore;
    private static KeyStore trustStore;
    public static HttpClient getSslHttpClient(Context pContext) {
        HttpClient httpsClient = new DefaultHttpClient();
        try {
            // 服务器端需要验证的客户端证书
            keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
            
            // 客户端信任的服务器端证书
            trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS);
            
            InputStream ksIn = pContext.getResources().getAssets().open(KEY_STORE_CLIENT_PATH);
            InputStream tsIn = pContext.getResources().getAssets().open(KEY_STORE_TRUST_PATH);
            try {
                keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());
                trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    ksIn.close();
                } catch (Exception ignore) {
                }
                try {
                    tsIn.close();
                } catch (Exception ignore) {
                }
            }
            SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore);
            Scheme sch = new Scheme(SCHEME_HTTPS, socketFactory, HTTPS_PORT);
            httpsClient.getConnectionManager().getSchemeRegistry().register(sch);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return httpsClient;
    }
}

2、android浏览器实现
1.先把你的CA证书拷贝到你的SD卡里面
2.进入手机的"设置"->"位置和安全",最下面有个"从SD卡安装",就是安装证书的。
---------暂时没有实现

---------------------------------------------上面复制自https://my.oschina.net/jjface/blog/339144---------------------------

---------------------------------------------下面复制自https://help.aliyun.com/document_detail/54508.html?spm=5176.11065259.1996646101.searchclickresult.5e90631306zyTa-------------------------------------------------------

本指南将引导您配置HTTPS双向认证的负载均衡服务。本指南中使用自签名的CA证书为客户端证书签名。

完成以下操作配置HTTPS监听(双向认证):

  1. 准备服务器证书
  2. 使用OpenSSL生成CA证书
  3. 生成客户端证书
  4. 上传服务器证书和CA证书
  5. 安装客户端证书
  6. 配置负载均衡实例
  7. 测试负载均衡服务

步骤一: 准备服务器证书

服务器证书用于用户浏览器检查服务器发送的证书是否是由自己信赖的中心签发的,服务器证书可以到阿里云云盾证书服务购买,也可以到其他服务商处购买。

步骤二: 使用OpenSSL生成CA证书

  1. 运行以下命令在/root目录下新建一个ca文件夹,并在ca文件夹下创建四个子文件夹。

     
       
    1. $ sudo mkdir ca
    2. $ cd ca
    3. $ sudo mkdir newcerts private conf server
    • newcerts目录将用于存放CA签署过的数字证书(证书备份目录)。
    • private目录用于存放CA的私钥。
    • conf目录用于存放一些简化参数用的配置文件。
    • server目录存放服务器证书文件。
  2. conf目录下新建一个包含如下信息的openssl.conf文件。

     
       
    1. [ ca ]
    2. default_ca = foo
    3. [ foo ]
    4. dir = /root/ca
    5. database = /root/ca/index.txt
    6. new_certs_dir = /root/ca/newcerts
    7. certificate = /root/ca/private/ca.crt
    8. serial = /root/ca/serial
    9. private_key = /root/ca/private/ca.key
    10. RANDFILE = /root/ca/private/.rand
    11. default_days = 365
    12. default_crl_days= 30
    13. default_md = md5
    14. unique_subject = no
    15. policy = policy_any
    16. [ policy_any ]
    17. countryName = match
    18. stateOrProvinceName = match
    19. organizationName = match
    20. organizationalUnitName = match
    21. localityName = optional
    22. commonName = supplied
    23. emailAddress = optional
  3. 运行以下命令生成私钥key文件。

     
       
    1. $ cd /root/ca
    2. $ sudo openssl genrsa -out private/ca.key

    运行结果如下图所示。

    2

  4. 运行以下命令并按命令后的示例提供需要输入的信息,然后回车,生成证书请求csr文件。

    $ sudo openssl req -new -key private/ca.key -out private/ca.csr

    注意:Common Name请输入您的负载均衡服务的域名。

    3

  5. 运行以下命令生成凭证crt文件。

    $ sudo openssl x509 -req -days 365 -in private/ca.csr -signkey private/ca.key -out private/ca.crt

  6. 运行以下命令为CA的key设置起始序列号,可以是任意四个字符。

    $ sudo echo FACE > serial

  7. 运行以下命令创建CA键库。

    $ sudo touch index.txt

  8. 运行以下命令为移除客户端证书创建一个证书撤销列表。

    $ sudo openssl ca -gencrl -out /root/ca/private/ca.crl -crldays 7 -config "/root/ca/conf/openssl.conf"

    输出为:

    Using configuration from /root/ca/conf/openssl.conf

步骤三: 生成客户端证书

  1. 运行以下命令在ca目录内创建一个存放客户端key的目录users

    $ sudo mkdir users

  2. 运行以下命令为客户端创建一个key:

    $ sudo openssl genrsa -des3 -out /root/ca/users/client.key 1024

    注意:创建key时要求输入pass phrase,这个是当前key的口令,以防止本密钥泄漏后被人盗用。两次输入同一个密码。

  3. 运行以下命令为客户端key创建一个证书签名请求csr文件。

    $ sudo openssl req -new -key /root/ca/users/client.key -out /root/ca/users/client.csr

    输入该命令后,根据提示输入上一步输入的pass phrase,然后根据提示,提供对应的信息。

    注意:A challenge password是客户端证书口令(请注意将它和client.key的口令区分开,本教程设置密码为test),可以与服务器端证书或者根证书口令一致。

    2

  4. 运行以下命令使用步骤二中的CA Key为刚才的客户端key签名。

    $ sudo openssl ca -in /root/ca/users/client.csr -cert /root/ca/private/ca.crt -keyfile /root/ca/private/ca.key -out /root/ca/users/client.crt -config "/root/ca/conf/openssl.conf"

    当出现确认是否签名的提示时,两次都输入y

    y

  5. 运行以下命令将证书转换为大多数浏览器都能识别的PKCS12文件。

    $ sudo openssl pkcs12 -export -clcerts -in /root/ca/users/client.crt -inkey /root/ca/users/client.key -out /root/ca/users/client.p12

    按照提示输入客户端client.key的pass phrase。

    再输入用于导出证书的密码。这个是客户端证书的保护密码,在安装客户端证书时需要输入这个密码。

    1

  6. 运行以下命令查看生成的客户端证书。

     
       
    1. cd users
    2. ls

    ls

步骤四: 上传服务器证书和CA证书

  1. 登录负载均衡管理控制台

  2. 实例管理页面,单击创建负载均衡

  3. 配置负载均衡实例,单击立即购买完成支付。

    注意:网络类型选择:公网,地域选择华东1。详细配置信息参考创建负载均衡实例

  4. 创建成功后,在实例管理页面,将鼠标移至实例名称区域,单击出现的铅笔图标,修改负载均衡实例名称。

  5. 负载均衡左侧导航栏,单击证书管理,然后单击创建证书,上传服务器证书。

  6. 创建证书页面,完成如下配置后,单击确定

    • 证书地域:本教程中选择华东1

      注意:证书的地域和负载均衡实例的地域要相同。

    • 证书类型:选择服务器证书

    • 证书内容和私钥:复制您的服务器证书内容和私钥。

      在复制内容前,您可以单击导入样式,查看正确的证书和私钥格式。更多详细信息查看证书要求

      2

  7. 在负载均衡左侧导航栏,单击证书管理,然后单击创建证书,上传CA证书。

  8. 创建证书页面,完成如下配置后,单击确定

    • 证书地域:本教程中选择华东1

      注意:证书的地域和负载均衡实例的地域要相同。

    • 证书类型:选择CA证书

    • 证书内容:复制您的CA证书内容。

      在复制内容前,您可以单击导入样式,查看正确的CA证书格式。更多详细信息查看证书要求

      4

步骤五: 安装客户端证书

将生成的客户端证书安装到客户端。本教程以Windows客户端,IE浏览器为例。

  1. 打开Git Bash命令行窗口,运行以下命令导出步骤三中生成的客户端证书。

    scp root@IPaddress:/root/ca/users/client.p12 ./

    注意:IPaddress是生成客户端证书的服务器的IP地址。

  2. 在IE浏览器中导入下载的客户端证书。

    1. 打开IE浏览器,单击设置 > Internet选项

    2. 单击内容页签,然后单击证书,导入下载的客户端证书。在导入证书时需要输入在步骤三时生成PKCS12文件的密码。

      5

步骤六: 配置HTTPS双向认证监听

  1. 登录负载均衡管理控制台

  2. 实例管理页面,单击华东1地域,然后单击已创建的负载均衡实例ID链接。

  3. 详情左侧导航栏,单击监听,然后单击添加监听

  4. 添加监听窗口,完成如下配置。

    • 前端协议 [端口]:HTTPS 443。

    • 后端协议 [端口]:HTTP 80。

    • 带宽峰值: 输入带宽峰值。

    • 调度算法:轮询。

    • 双向认证:开启。

    • 服务器证书:选择已上传的服务器证书。

    • CA证书: 选择已上传的CA证书。

    • 单击下一步,然后单击确认完成配置。

      6

  5. 详情左侧导航栏,单击服务器 > 后端服务器,然后单击添加后端服务器,添加ECS服务器。

步骤七: 测试HTTPS双向认证

  1. 实例管理页面,查看健康检查状态。当状态为正常时,表示后端服务器可以正常接收处理负载均衡监听转发的请求。

    8

  2. 在浏览器中,输入负载均衡的公网服务地址,当提示是否信任客户端证书时,选择信任。

    8

  3. 刷新浏览器,您可以观察到请求在两台ECS服务器之间转换。

    因为使用了自建的服务器证书,所以下图示例中会有不信任提示。

    9

    0



猜你喜欢

转载自blog.csdn.net/qq_15003505/article/details/80079467