java httpclinet请求https地址报java.io.IOException: Invalid keystore format 解决办法

=这又是一次生产问题协查,痛苦的协查。起因是合作方调用地址变更,变更后的地址是https协议地址,对方新增了一个.jks的证书库要加载

代码写完后,一上线发https请求就报错,因为合作方封装了一个sdk的包,报错堆栈信息没有向上返回,是返回了一个“加密失败”,哎。。。。

这里只能把ssl debug打开来,打开方法不太清楚的参考另一篇文章 java ssl调试打开ssl debug日志

打开后日志看到两个异常:

java.io.IOException: Invalid keystore format
	at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:650)
	at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
	at java.security.KeyStore.load(KeyStore.java:1445)
	at cfca.httpclient.connector.HttpClient.initSSL(HttpClient.java:77)
	at cfca.httpclient.connector.HttpConnector.init(HttpConnector.java:31)
qtp418304857-24, handling exception: 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
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:1937)
	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:1478)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1050)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
	at cfca.httpclient.connector.HttpClient.send(HttpClient.java:152)
	at cfca.httpclient.connector.HttpConnector.deal(HttpConnector.java:74)
	at cfca.httpclient.connector.HttpConnector.post(HttpConnector.java:47)

不知道脑子怎么想的,上来就查第二个异常,花了2天,想了各种办法,然而没有解决(路走错了怎么能到达终点呢。。。),事实证明,第一个问题解决后,第二个异常也就跟着没了。查第二个问题看到的一篇文章,虽然没用到,但是感觉写的不错:How to resolve “unable to find valid certification path to requested target” error ? 后面就是加紧解决第一个问题

在网上看到一些处理办法,说是maven-resources-plugin 在拷贝resources 文件时进行 encoding  会“误伤二进制文件”导致拷贝到classes下的文件发生了变化.

我对比了一下,果不其然,对比了下src/main/resources下的jks 文件和生产运行的classes下的文件大小不一致,classes目录下的文件大了一圈. 嗯,看看别人的处理办法, filtering=false

    <resources>  
        <resource>  
            <directory>src/main/resources</directory>  
            <filtering>false</filtering>  
        </resource>  
    </resources>  

赶紧去修改自己的pom.xml,打开自己的pom要修改的时候看到代码:

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources/certificate</directory>
                <filtering>false</filtering>
            </resource>

        </resources>

 filtering已经是false了,没毛病,但是还是不行,这是为啥?(certificate目录下是.jks文件),看到个别有的文章说配置了filtering=false 没效,估计跟我这配置应该是差不多的,参考下面的方法:

后来调整了一下配置:

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>certificate/*.jks</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>certificate/*.jks</include>
                </includes>
            </resource>
        </resources>

再用maven构建,构建后的.jks文件大小正常,没有再变大了!项目部署后,请求https地址也能正常返回了。。。

还看到另外一种配置方式:

<build>
  ...
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>                
      <configuration>
        <nonFilteredFileExtensions>
           <!--这里是文件后缀-->
          <nonFilteredFileExtension>jks</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
      </configuration>
    </plugin>
  </plugins>
</build>

因为上面的配置生效了,下面这个方法就没有尝试。有兴趣的小伙伴可以自己动动手!希望记下的这次处理过程对大家也有帮助!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值