程序引用信任库方式发起https请求

一、前言

OS:Windows10 64

Tomcat:Tomcat 7.0

证书格式:.jks格式证书,因为该示例为tomcat方式

 

二、Tomcat相关配置

1、首先你的应用服务器是tomcat的话,需要使用jks证书,没有可以自签证书。自签证书方式可参考【Windows下自签jks格式证书】。

 

2、在tomcat目录下新建【cert】目录,将.jks格式证书放在该文件夹下(此步操作的目的是为了方便单应用服务情况下,证书管理的方便)。

 

3、配置【server.xml】,在该配置文件中添加如下配置信息:

<Connector port="设置https访问端口,默认443,可自定义"
               protocol="org.apache.coyote.http11.Http11Protocol"
               SSLEnabled="true"
               scheme="https"
               secure="true"
               keystoreFile="jks文件的存放全路径"
               keystorePass="证书密码"
               clientAuth="false"
               SSLProtocol="TLSv1.1+TLSv1.2+TLSv1.3"
               ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256"/>

 

4、启动tomcat服务。

 

三、HTTPS访问程序及程序请求发起

1、没有引用证书信任库,直接发起https请求,会报如下错误信息:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
    at com.example.utils.RequestUtil.sendPost(RequestUtil.java:32)
    at com.example.utils.RequestUtil.main(RequestUtil.java:24)

 

2、导入证信任,并查看证书导入的是否正确(通过证书指纹对比校验证书是否导入正确)。

# 导入.crt或者.cer证书到信任文件中,统一管理
命令:keytool -import -alias ca_cert_test -file cert.crt -keystore cacerts.truststore
输出:输入密钥库口令:
再次输入新口令:
所有者: OU=HangZhou, L=HangZhou, ST=ZheJiang, C=CN
发布者: OU=HangZhou, L=HangZhou, ST=ZheJiang, C=CN
序列号: 4af0e8374167c39db8e3a09bd8990fb56cafca0
有效期开始日期: Fri Oct 28 19:58:48 CST 2022, 截止日期: Sun Nov 27 19:58:48 CST 2022
证书指纹:
         MD5: 66:C7:F4:7E:A2:F8:7E:D1:59:FC:7C:CD:73:E5:18:D7
         SHA1: 99:3D:83:1F:0B:DA:E9:9A:51:78:21:A6:C9:51:72:A4:2F:58:C2:18
         SHA256: 34:41:08:54:7B:A1:96:17:DE:67:26:56:88:ED:39:84:1F:E0:0E:DA:04:40:6A:D4:B3:48:13:D1:0D:34:16:DB
         签名算法名称: SHA256withRSA
         版本: 3

扩展:

#1: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:false
  PathLen: undefined
]

#2: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
  DigitalSignature
  Non_repudiation
  Key_Encipherment
]

#3: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  IPAddress: 192.168.1.102
]

是否信任此证书? [否]:  y
证书已添加到密钥库中

#查看导入的证书信息是否正确
命令:keytool -list -keystore cacerts.truststore -storepass 密码
输出:

密钥库类型: JKS
密钥库提供方: SUN


您的密钥库包含 1 个条目


ca_cert_test, 2022-10-29, trustedCertEntry,
证书指纹 (SHA1): 99:3D:83:1F:0B:DA:E9:9A:51:78:21:A6:C9:51:72:A4:2F:58:C2:18


 

 

 

3、请求程序引用配置好的信任库文件,然后进行https请求,操作如下:

# 请求程序
private static final String TRUSTSTORE_PATH="证书信任文件的全路径";
    private static final String TRUSTSTORE_PWD="密码";

    public static void main(String[] args) throws Exception {
        String url="https://192.168.1.102:8099/tt/test";
        String params="{\"测试\":\"测试tt\"}";
        sendPost(url,params);
    }

    public static void sendPost(String url,String params) throws Exception{
        System.setProperty("javax.net.ssl.trustStore",TRUSTSTORE_PATH);
        System.setProperty("javax.net.ssl.trustStorePassword",TRUSTSTORE_PWD);
        CloseableHttpClient client= HttpClients.createDefault();
        HttpPost post=new HttpPost(url);
        StringEntity entity=new StringEntity(params,"UTF-8");
        post.setEntity(entity);
        CloseableHttpResponse response=client.execute(post);
        if(response.getStatusLine().getStatusCode()==200){
            String body= EntityUtils.toString(response.getEntity());
            System.err.println("请求响应的响应体内容:"+body);
        }
    }
10:39:00.512 [main] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: default
10:39:00.537 [main] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
10:39:00.541 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://192.168.1.102:8099][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
10:39:00.578 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {s}->https://192.168.1.102:8099][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
10:39:00.582 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {s}->https://192.168.1.102:8099
10:39:00.590 [main] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to /192.168.1.102:8099
10:39:00.590 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Connecting socket to /192.168.1.102:8099 with timeout 0
10:39:00.622 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Enabled protocols: [TLSv1, TLSv1.1, TLSv1.2]
10:39:00.622 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Enabled cipher suites:[TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
10:39:00.623 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Starting handshake
10:39:00.716 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Secure session established
10:39:00.716 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory -  negotiated protocol: TLSv1.2
10:39:00.716 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory -  negotiated cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
10:39:00.717 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory -  peer principal: OU=HangZhou, L=HangZhou, ST=ZheJiang, C=CN
10:39:00.717 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory -  peer alternative names: [192.168.1.102]
10:39:00.717 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory -  issuer principal: OU=HangZhou, L=HangZhou, ST=ZheJiang, C=CN
10:39:00.722 [main] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connection established 192.168.1.102:59949<->192.168.1.102:8099
10:39:00.722 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request POST /tt/test HTTP/1.1
10:39:00.723 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED
10:39:00.724 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> POST /tt/test HTTP/1.1
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Length: 21
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Type: text/plain; charset=UTF-8
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Host: 192.168.1.102:8099
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Connection: Keep-Alive
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_131)
10:39:00.726 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
10:39:00.726 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "POST /tt/test HTTP/1.1[\r][\n]"
10:39:00.726 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Length: 21[\r][\n]"
10:39:00.726 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Type: text/plain; charset=UTF-8[\r][\n]"
10:39:00.727 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Host: 192.168.1.102:8099[\r][\n]"
10:39:00.727 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
10:39:00.727 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_131)[\r][\n]"
10:39:00.727 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
10:39:00.727 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
10:39:00.727 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "{"[0xe6][0xb5][0x8b][0xe8][0xaf][0x95]":"[0xe6][0xb5][0x8b][0xe8][0xaf][0x95]tt"}"
10:39:00.735 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]"
10:39:00.735 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Server: Apache-Coyote/1.1[\r][\n]"
10:39:00.735 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Content-Length: 0[\r][\n]"
10:39:00.735 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Date: Sat, 29 Oct 2022 02:39:00 GMT[\r][\n]"
10:39:00.735 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
10:39:00.742 [main] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 200 OK
10:39:00.742 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Server: Apache-Coyote/1.1
10:39:00.742 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Content-Length: 0
10:39:00.743 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Date: Sat, 29 Oct 2022 02:39:00 GMT
10:39:00.753 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection can be kept alive indefinitely
10:39:00.754 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {s}->https://192.168.1.102:8099] can be kept alive indefinitely
10:39:00.754 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0
10:39:00.754 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://192.168.1.102:8099][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
请求响应的响应体内容:
Disconnected from the target VM, address: '127.0.0.1:59939', transport: 'socket'

Process finished with exit code 0

 

 

四、友情提示

1、keytool命令为jdk自带命令,jdk配置好全局变量即可。

posted @ 2022-10-29 10:54  lightbc  阅读(220)  评论(0编辑  收藏  举报