解决:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExcep—SSL证书导入Java信任库

一、前言背景

        笔者使用第三方SDK实现API调用,本地开发及测试均OK。但是现场服务器没有外网,需要使用内外网代理实现API的调用。

        常规情况为了省事我们都会使用一行代码来跳过SSL校验:SslUtil.ignoreSsl();

        可这次用的是SDK,它内部封装了okhttp的对象,无法使用公共方式跳过SSL校验,于是就有了这篇笔记,记录“阳光大道”下顺利通过证书校验。

二、发现问题

        现场使用nginx进行代理转发,没有配置证书的情况下后台直接报错:

        错误信息:{"statusCode":-1,"message":"SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target","code":"network error","isJson":false}

        大体意思就是找不到对应SSL证书,排查Nginx日志为空,可以确认该报错是Java自己内部拦截并提示的。按照不走代理的情况下是可以直接访问API,所以这种情况一定是Java去找Nginx要证书,结果Nginx没给,或者给了个驴头不对马嘴的自签证书。

        Java:用户要访问阿里云API,给我一下 aliyuncs.com的证书

        Nginx:给——https.crt

        Java:不是哥们,你这证书保真吗?看着像是个自签证书啊

        Nginx:你是找事儿啊还是验证书啊,我一个代理网络的能给你假证书吗?

        Java:行行,那你给我包起来返回吧

        Nginx:(骂骂咧咧嘟囔着返回了证书信息)

        Java:unable to find valid certification path,用户请求了但是没找到证书,去和我的 rm刀解释吧!

三、解决方案

        Nginx的证书不仅被Java “ 砍 ” 了,Nginx自己都差点 “嘎” 了。

        回归正题,Nginx自己签发的证书是不被第三方API认可的,所以还是得想办法找到第三方API请求地址对应的证书文件,单个域名可以直接使用openssl导出证书。

--根据域名导出crt证书 D:\OpenSSL-Win64\bin\openssl.exe s_client -connect dashscope.aliyuncs.com:443 -servername dashscope.aliyuncs.com <NUL 2>NUL | D:\OpenSSL-Win64\bin\openssl.exe x509 -outform PEM -out F:/dashscope.crt

        如果有多个请求地址需要生成组合域名的证书文件:

        参考地址:Nginx多域名HTTPS配置全攻略:从证书生成到客户端安装

        好了,这下我们拿到的证书文件,接下来就要把它交给Java信任库,不然它自己还是不认可这个证书,所以必须:请求地址证书、Java信任库证书、Nginx证书,三者保持一致才可以。

--证书添加到java信任库,密码changeit keytool -import -alias amapaliyun-www -keystore "D:\JDK1.8\jre\lib\security\cacerts" -file "D:\nginx-1.19.7_B\conf\cert\amapaliyun.crt" -storepass changeit -noprompt
--查看信任库中的证书 keytool -list -keystore "D:\JDK1.8\jre\lib\security\cacerts" -alias amapaliyun-www -storepass changeit

        至此,我们就把证书全部配置完成,然后重新启动服务,重新启动Nginx进行测试验证即可。

四、总结回顾

        写这篇笔记总共花了二十分钟,其中五分钟还是在找华强砍瓜的图片,但实际排查问题解决问题足足花了三个多小时。这里总结回顾主要是想记录一下,遇到问题后一定要先定位问题点而不是乱猜乱试。比如本文的问题,只有定位到那个报错是Java返回的就已经解决了一大半,剩下的只要正向推理尝试便不会再耽误时间。而笔者却在生成的证书上花了很长时间确认它是否有问题,其实只需要查看Nginx日志便可以划分出来,记录,共勉。

Read more

【C++写详细总结①】从for循环到算法初步

【C++写详细总结①】从for循环到算法初步

前言 本文通过小编自身学习的进程从而总结出本文,也希望大家可以好好学习,帮助到自己 这个是萌新考场救场代码,与本文一起食用更佳 for循环计数器 for(定义计数变量;定义结束条件;每次循环所做的动作) 示例 for(int i=1;i<=10;i++) //首先定义“i”变量作为计数数组,赋初值为“1”//然后每次循环判断条件是否成立,不成立则退出//最后每循环执行条件,此示例为每循环“i”增加1 而计数器就是在for循环有了一定执行范围的基础上创建了一个数组,进行++计数 示例 #include<iostream>// 万年不变的框架usingnamespace std;intmain(){int n; cin>>n;//输入数值表示从1~n中有几个数字int

By Ne0inhk
【C++笔记】模板初阶

【C++笔记】模板初阶

前言:         C++模板是C++中实现泛型编程的核心工具,允许程序员编写与类型无关的代码,从而提高代码的复用性和灵活性。模板在编译时进行实例化,根据实际使用的类型生成具体的代码,因此不会带来运行时开销。          一、模板基础          1.1 为什么需要模板?          在编写函数或类时,如果希望它们能处理多种数据类型(如int、double、string),传统方法是使用函数重载,但这样会产生大量重复代码或失去类型信息。 模板允许将类型作为参数,编译器根据调用时传入的具体类型生成对应的代码。          场景:需要编写一个求两个数最大值的函数,支持 int、double 和 string(按字典序)。          ①传统方法:函数重载 #include <iostream> #include <string> using namespace std; // 为 int 重载 int max(int

By Ne0inhk
Re:从零开始的 C++ 进阶篇(二)C++继承到底做了什么?从对象模型到底层内存布局彻底讲透

Re:从零开始的 C++ 进阶篇(二)C++继承到底做了什么?从对象模型到底层内存布局彻底讲透

◆ 博主名称: 晓此方-ZEEKLOG博客大家好,欢迎来到晓此方的博客。⭐️C++系列个人专栏: 主题曲:C++程序设计⭐️ 踏破千山志未空,拨开云雾见晴虹。 人生何必叹萧瑟,心在凌霄第一峰 0.1概要&序論 这里是此方,好久不见。 继承是 C++ 中最核心却最易被误解的机制之一。它不仅关乎语法层面的扩展,更涉及对象模型、内存布局与多态实现。本文将从底层原理出发,系统解析继承的真实运作机制。这里是「此方」。让我们现在开始吧! 一,初识继承 1.1 继承的概念与使用方法导入 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在 保持原有类特性的基础上进行扩展,增加方法(成员函数)和属性(成员变量),这样产生新的类,称为 派生类。 继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的函数层次的复用,继承是类设计层次的复用。

By Ne0inhk
深入解剖STL map/multimap:接口使用与核心特性详解

深入解剖STL map/multimap:接口使用与核心特性详解

❤️@燃于AC之乐 来自重庆 计算机专业的一枚大学生 ✨专注 C/C++ Linux 数据结构 算法竞赛 AI 🏞️志同道合的人会看见同一片风景! 👇点击进入作者专栏: 《算法画解》 ✅ 《linux系统编程》✅ 《C++》 ✅ 🌟《算法画解》算法相关题目点击即可进入实操🌟 感兴趣的可以先收藏起来,请多多支持,还有大家有相关问题都可以给我留言咨询,希望希望共同交流心得,一起进步,你我陪伴,学习路上不孤单! 文章目录 * 前言(map系列容器概述) * 一、map类介绍 * 1.1 map的类模板声明 * 二、pair类型介绍 * 2.1 pair的结构定义 * 2.2 pair的使用要点 * 三、map的构造与迭代器 * 3.1 构造接口 * 3.2 迭代器接口 * 四、map的增删查操作

By Ne0inhk