javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

这里写图片描述

Hello,小伙伴好久不见!今天在联调接口时,遇到一个错误,纠结了好久才解决.虽然是粗心引起的,但是也大概明白了引起这个错误的来龙去脉,现在整理一下,分享给大家,希望大家在遇到这个类似问题了,不会太无助;

前言

我们来看下问题发生的大背景;这次我们联调是一个获取单笔订单详情的接口,采用https请求方式.我方是请求方,现需请求能力开发平台(对方)的接口

1.Https加密认证过程是什么样的?

我们来看看接口文档的描述(对方视角):
能力开放平台接口传输采用HTTPS加密传输。接口为RESTFul风格的WebService,信息交互过程为用户按我方提供的webservice地址进行调用,我方接到调用请求后,为用户返回JSON格式组织的信息,用户依据约定的接口规范对数据进行解析。它将用户与移动商城开放平台之间传输的内容进行加密认证。使内容的传输处于安全的加密状态,以防止数据在传输中途被窃取。
客户端认证:由能力开放平台为各个商户自有系统颁发客户端的自签发SSL证书和密钥,通过该证书和密钥来访问能力开放平台接口。
能力开放平台使用自身的根证书为商户自有系统颁发客户端证书和密钥:

  • client.crt:客户端证书文件
  • client.key : 客户端密钥文件
  • 客户端证书密码

2.什么是SSL证书?

SSL 证书就是遵守 SSL协议,由受信任的数字证书颁发机构CA,在验证服务器身份后颁发,具有服务器身份验证和数据传输加密功能。

3.环境情况

  • jdk1.7
  • httpclient_4.2.1.jar

一.场景再现

当我们请求对方接口时,发现报了如下错误

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

这里写图片描述

二.刨根问底

1.温故知新

遇到未见过错误,第一时间拿报错信息去问了度娘,首先发现这位兄台的博客,是我明白了
在我们分析什么原因导致了这个问题之前,我们需要搞明白一件事:https的socket工作原理是怎样的?
https的socket工作原理流程图如下:
这里写图片描述
接下来,我们需要搞清楚什么原因会导致这类报错,下面这边博客可以给我们一些思路;peer not authenticated的终极解决方案
在这边文章中,作者介绍可能引发这个报错的几种原因,总结如下:
  首先,要知道导致报这个异常的原因不仅仅是因为证书校验不通过。
  1.在我们通过https链接服务器时,服务器会给我们返回一个证书,这个证书可能经过CA认证,也可能是未认证的自制证书,客户端拿到这个证书后会对这个证书进行验证,如果是经过CA验证的证书,自然证书校验就能通过,自制证书自然就校验不同过,从而导致上边的异常。
  2.证书校验通过后,还需要校验访问的域名是否和证书指定的域名是否匹配。未匹配也会导致如上异常。
  3.上边两步都校验通过了才开始进行握手,但握手也有可能失败,从而导致上边的异常。
  以上三个步骤中任何一个出了问题,都会连接失败。
###2.问题探究
根据报错信息的堆栈信息,我去跟踪了源码,发现在错误的发送在SSLSessionImpl类的下面方法中
这里写图片描述

public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
    if(this.cipherSuite.keyExchange != KeyExchange.K_KRB5 && this.cipherSuite.keyExchange != KeyExchange.K_KRB5_EXPORT) {
        if(this.peerCerts == null) {
            throw new SSLPeerUnverifiedException("peer not authenticated");
        } else {
            return (Certificate[])((Certificate[])this.peerCerts.clone());
        }
    } else {
        throw new SSLPeerUnverifiedException("no certificates expected for Kerberos cipher suites");
    }
}

根据如上源码,我们发现只有peerCerts==null时候,才导致了报错.继续跟踪源码,我们发现下面的方法会给他赋值
这里写图片描述

void setPeerCertificates(X509Certificate[] var1) {
    if(this.peerCerts == null) {
        this.peerCerts = var1;
    }

}

现在有一个问题,什么时候我们会调用这个方法去给他赋值?这个问题困扰了好久,直到看到这位大佬的文章:jdk6出现peer not authenticated问题原因分析与解决
在这篇文章中,我们发现peerCerts是用来存储服务端返回的证书;附上文章中作者的一段代码
1.httpclient未获取到服务器证书
这里写图片描述
2.httpclient获取到了服务器证书
这里写图片描述
这样,我们就基本定位问题原因:没有获取到服务端证书;

三.解决方案

当我们去搜这个问题解决方案时,会发现很多都是重写底层的验证方法来绕过校验,可能这种解决思路适合需要发起https请求,但是没有证书的情况;
因为本次接口调用时一定需要证书的,所以这类解决思路并不适合我,定位了问题的原因以后,经过排除居然是请求地址未加端口号,导致无法获取到服务端证书;

重要的事情说三遍:细心,细心,细心!!!

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
nutch javax.net.ssl.sslexception : could not generate dh keypair 是一个SSL异常,意味着Nutch无法生成DH密钥对。 TLS(Transport Layer Security)是一种加密协议,用于保护在网络上进行的通信。在TLS握手期间,服务器和客户端会协商加密算法和生成共享密钥对。 DH(Diffie-Hellman)密钥交换是TLS协议中常用的一种加密算法。它允许服务器和客户端在不直接传递密钥的情况下,通过交换公钥来生成共享密钥。 nutch javax.net.ssl.sslexception : could not generate dh keypair 错误意味着Nutch无法生成DH密钥对。这可能是由于以下几个原因导致的: 1. Java安全性策略限制:Java默认情况下,限制了密钥长度。您可以尝试通过修改Java安全性策略文件来解决此问题。 2. 加密算法不受支持:您使用的Java版本可能不支持所需的加密算法。您可以尝试升级到较新的Java版本。 3. 随机数生成器问题:DH密钥对需要使用随机数生成器生成随机数。但是,如果随机数生成器不可用或出现故障,就会出现此错误。您可以尝试重新配置随机数生成器或更换可靠的实现。 4. SSL证书问题:此错误可能是由于证书问题引起的。您可以检查证书是否过期或不匹配,并尝试更新或更换证书。 针对这个错误,您可以逐一排查上述情况,并尝试相应的解决方法来解决该问题。如果问题仍然存在,您可能需要进一步的调查和故障排除来确定准确的原因并解决问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值