调取Https接口遇到的坑及解决方式

目录

踩坑的过程

背景

前提

开始排查问题原因

 结论

关于Https协议的接口

Java实现调取Https接口方式

1.RestTemplate跳过验证

2.校验方式

3.Forest框架调取接口

参考文档


踩坑的过程

背景

现在有一个平台提供的接口,是Https形式的,但是呢,提供的文档上写的是Http,他们还好心付上了代码样例,你以为这样就可以CV了吗,想简单了,年轻人。

但在实际调取的时候发现,接口不通,负责人告诉我,这就是简单的https接口,你们调就行,直到把缺少证书的报错发给他,才给我一个server.pem,一个server.key,使用这两个文件调取,还是出现问题;

后来又给了一个pem文件,使用这个最新的文件调接口,还是报错,更换了各种调取接口的代码后,依旧是一样的错误;

前提

1.因为服务端禁止ping,采用telnet命令(没有的话需要先安装)

2.这个台服务器上hosts文件也做了IP对域名的映射

3.服务器上的DNS设置也做了


开始排查问题原因

1.先使用keytool命令,将最新的pem证书文件导入客户端服务器的JDK中

keytool -import -v -trustcacerts -alias mycacerts -file radiance-com-cn.pem -storepass changeit -keystore JDK/jre/lib/security/cacerts

2.查看导入的证书

keytool -list -keystore "JDKfile/jdk1.8.0_131/jre/lib/security/cacerts" -storepass changeit 

3.使用curl命令调取接口并查看结果

curl -v https://xxxxxxxx

curl命令需要支持https协议

若curl不支持https协议,再看下服务器上是否存在openssl主件

4.尝试使用代码调接口,也是不行的,一直是报错,connect reset

java.net.SocketException: Connection resetat java.net.SocketInputStream.read(SocketInputStream.java:209) ~[?:1.8.0_102]at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[?:1.8.0_102]

5.抓包

在https客户端这边抓包,结果是TCP三次握手之后,客户端开始SSL验证,向服务端发送了client hello,服务端返回了reset,将这次连接拆掉了,后边的SSL/TSL校验也不存在了;


在服务端抓包看,是43600发送来的reset,这个和上面服务端上对不上的!

 结论

所以,看到这里,只能证明,在客户端服务器和服务端服务器之间还有其他的网络设备,导致的网络问题,进而导致的客户端和服务端抓包不一致的

将这个抓包和现象给平台的负责人反馈后,也不知道他们改了什么东西,就可以调通接口了,下面的事情就好办了,照着抓包进行调接口就行;

高呼:抓包yyds!

实际接口入参、返回值和原文档对不上这种事情太常见了...

关于Https协议的接口

Https接口是和Http接口不同的,在Http的上面加了一层SSL/TSL证书校验;

一般调取的方式为跳过证书的验证,直接访问接口,跳过的方式也又很多种,我一开始采用的是RestTemplate的方式;

SYN:Synchronize Sequence Numbers 同步序列编号

ACKAcknowledge character 确认字符

RST:reset

 一次正常的双向验证如下图所示

 先进行TCP的三次握手,握手成功后

1.客户端向服务端发送client hello,携带客户端这边支持的加密套件,32位随机数发送给服务端

2.服务端收到client hello后,回复ACK

3.服务端接着回复Server Hello,并且生成随机数、Ciper Suite使用的加密算法,tls的版本这里我们使用的是TLS v1.2;

4.客户端收到Server Hello后,回复ACK

5.接着,服务端将生成公钥和私钥,私钥保留将公钥发送给客户端,以认证身份,并且发送Server Hello Done表示Server Hello结束;

6.客户端收到服务端的证书回复ACK

7.客户端将证书发送给服务端,进行证书的交换Client key Exchange,生成一对公钥和私钥,公钥发给服务端;

8.服务端收到之后,回复ACK

9.客户端和服务端进行交换,开始使用最开始协商好了的密钥,服务端收到后回复ACK

 10.客户端根据交互过程中交换的信息,以及服务端的密码套件,生成了相对应的密匙

encrypted handshake message:客户端通过发送一段加密后的finished的信息给服务端,是为了证明刚才握手建立起来的加密通信;

Java实现调取Https接口方式

java代码层面实现调取Https方式有很多种,下面简单介绍几种,都是CV的网上的代码,直接拿来用即可,不需要重复造轮子

1.RestTemplate跳过验证

@Configuration
public class RestTemplateConfig {/*** restTemplate跳过Https接口 SSL认证** @return*/@Beanpublic RestTemplate restTemplate() {RestTemplate restTemplate = new RestTemplate();restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));return new RestTemplate(generateHttpRequestFactory());}private HttpComponentsClientHttpRequestFactory generateHttpRequestFactory() {TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;SSLContext sslContext = null;try {sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {e.printStackTrace();}SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());HttpClientBuilder httpClientBuilder = HttpClients.custom();httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);CloseableHttpClient httpClient = httpClientBuilder.build();HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();factory.setHttpClient(httpClient);return factory;}
}

在http工具类中直接使用restTemplate调取接口即可

2.校验方式

进行校验的方式有很多种,在上述案例踩坑的过程中,在网上找了很多使用证书验证的方式,也写了很多测试的方法尝试着去调取他们的接口,但是都是报错了;

这块有很多种方式,但是由于平台方给的证书不符合要求就不一一列举了,chatgpt确实帮了大忙,嘎嘎一顿写

现在先写这一个,之后慢慢研究

以下代码通过chatgpt生成,并未通过实际验证,慎用!!!

/*** 使用pem进行SSL校验,调取https接口,post请求** @param httpsUrl     接口URL* @param body         入参* @param keystoreFile pem文件路径* @param keystorePass pem文件密码* @param sslType      SSL的类型* @return 调取接口的返回*/public String sendPostByHttps(String httpsUrl, JSONObject body, String keystoreFile, String keystorePass, String sslType) {try {//设置可通过ip地址访问https请求HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());URL url = new URL(httpsUrl);HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();// 在连接之前先设置SSL上下文SSLContext sslContext = SSLContext.getInstance(sslType);// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = {new MyX509TrustManager(keystoreFile, keystorePass)};sslContext.init(null, tm, new java.security.SecureRandom());conn.setSSLSocketFactory(sslContext.getSocketFactory());// 后续操作以及可以正常进行 HTTPS 请求了         conn.setRequestMethod("POST");conn.setDoOutput(true);// 打开输出流,以便向服务器提交数据conn.setDoInput(true); // 打开输入流,以便从服务器获取数据PrintWriter out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));out.print(body.toJSONString());out.flush();out.close();int responseCode = conn.getResponseCode();log.info("调取接口,HTTPS返回状态码为:{}", responseCode);if (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStreamRes = conn.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStreamRes));String line;StringBuilder result = new StringBuilder();while ((line = reader.readLine()) != null) {result.append(line);}reader.close();inputStreamRes.close();return result.toString(); //即为接口的返回}} catch (Exception e) {log.error("请求HTTPS接口,请求失败 | e = {}", e.getMessage(), e);}return null;}
public class MyX509TrustManager implements X509TrustManager {private X509TrustManager sunJSSEX509TrustManager;MyX509TrustManager(String keystoreFile, String pass) throws Exception {KeyStore ks = KeyStore.getInstance("JKS");ks.load(new FileInputStream(keystoreFile), pass.toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE");tmf.init(ks);TrustManager[] tms = tmf.getTrustManagers();for (TrustManager tm : tms) {if (tm instanceof X509TrustManager) {sunJSSEX509TrustManager = (X509TrustManager) tm;return;}}throw new Exception("Couldn't initialize");}@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {try {sunJSSEX509TrustManager.checkClientTrusted(chain, authType);} catch (CertificateException excep) {excep.printStackTrace();}}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {try {sunJSSEX509TrustManager.checkServerTrusted(chain, authType);} catch (CertificateException excep) {excep.printStackTrace();}}@Overridepublic X509Certificate[] getAcceptedIssuers() {return sunJSSEX509TrustManager.getAcceptedIssuers();}}

3.Forest框架调取接口

此方法经过验证是可以的,也是上手最快的;

🎁 新手介绍 | Forest (dtflyx.com)

pom依赖

   <dependency><groupId>com.dtflys.forest</groupId><artifactId>forest-spring-boot-starter</artifactId><version>1.5.0</version></dependency>

properties文件中配置项

#配置后端HTTP-API为okhttp3
forest.backend=okhttp3
#forest组件中是否开启日志打印总开关
forest.log-enabled=false
#forest组件中id值
forest.ssl-key-stores.id=myhttpstest
#forest组件中证书的路径
forest.ssl-key-stores.file=
#forest组件中密匙没有空着
forest.ssl-key-stores.keystore-pass=
#forest组件中密匙没有空着
forest.ssl-key-stores.cert-pass=
#forest组件中加密的版本
forest.ssl-key-stores.protocols=TLSv1.2
public interface HttpsClient {/*** Https接口测试** @param url       接口名* @param param     入参* @param headerMap 接口的Header* @return*/@Post(url = "${url}", keyStore = "myhttpstest")ForestResponse<String> getHttpsTest(@DataVariable("url") String url,@JSONBody String param,@Header Map<String, Object> headerMap);

在Application启动类中加上如下注解

@ForestScan(basePackages = "com.test.forest")
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

直接将HttpsClient注入调取接口的业务方法中,通过方法调用的形式即可实现接口的调用,具体的原理呢,框架已经帮我们实现了,不用重复的写那么多的代码了;

....ForestResponse<String> resultEntity = httpClient.getIdmPersonInfo(url, param.toString(), headerMap);

参考文档

https://blog.csdn.net/qq78442761/article/details/120149824

wireshark抓包分析HTTPS - 知乎 (zhihu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/12357.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NLP】LSTM 唐诗生成器

目标&#xff1a;使用 github 唐诗宋词数据库的 json 数据&#xff0c;训练一共唐诗生成器 数据源&#xff1a;https://github.com/chinese-poetry/chinese-poetry 查看原始数据格式 原始数据包含 作者、正文、标题、id四个部分&#xff0c;这里仅仅使用诗词正文进行训练 …

大力推广 Bard 的谷歌,警告自家员工:慎用 AI 聊天机器人!

整理 | 郑丽媛 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 有了去年 ChatGPT 的领跑后&#xff0c;此后各家科技巨头都陆续在 AI 领域积极布局&#xff0c;其中谷歌的 Bard 更被业界视作 ChatGPT 的有力竞争者。 因此很难想到&#xff0c;Alphabet&#xff0c…

GPT-4测评,大家先别急,图片输入还没来

昨天GPT-4朋友圈刷屏&#xff0c;我更新了一篇小文章&#xff0c;极简罗列GPT-4的一些情报&#xff1a; 1 ChatGPT Plus用户才可试用GPT-4 2 试用阶段每四小时最多100条信息 3 知识库还是2021年 4 上下文长度为8192个token 5 是多模态&#xff0c;但是图片输入仍处于研究预…

chatgpt赋能Python-pythonlabels

Python Labels: 了解Python中标签的作用 Python是一种流行的编程语言&#xff0c;它有着广泛的应用场景。在Python中&#xff0c;标签&#xff08;Labels&#xff09;是一个非常重要的概念&#xff0c;可以帮助开发者更好地组织代码和进行调试。本文将介绍Python中的标签&…

dede采集插件自动采集文章图片自定义接口

为什么要用Dede采集插件&#xff1f;如何利用免费Dede采集插件让网站收录以及关键词排名。我们知道&#xff0c;网站结构是seo优化过程中不可忽视的一个非常重要的环节&#xff0c;网站结构分为物理结构和逻辑结构&#xff0c;物理结构一般指的是虚拟空间中很多目录和文件的摆放…

呼吁!少用ChatGPT,多支持开源!

【深度学习革命 - 从历史到未来 Genius Makers: The Mavericks Who Brought AI to Google, Facebook, and the World】这本书里详述了为何西方人工智能界&#xff08;AI&#xff09;对于 AI 如此戒慎恐惧&#xff0c;深忧它被少数白人&#xff08;绝大多数为男性&#xff09;统…

ChatGPT对未来教育的影响:或将成为奇点

ChatGPT横空出世&#xff0c;不难想象&#xff0c;不久的将来&#xff0c;公司经理只要按一下按钮或者对语音机器人发个指令&#xff0c;就可以将一个粗略的文档转换成优雅的演示文稿&#xff0c;而无需劳烦公司文秘。这无疑颠覆了我们早已熟稔于心的工作场景。 不论是这一次人…

“慎用ChatGPT”!

中国财经报 2023-04-11 4月10日&#xff0c;中国支付清算协会网站发布“关于支付行业从业人员谨慎使用ChatGPT等工具的倡议”&#xff0c;全文如下&#xff1a; 近期&#xff0c;ChatGPT等工具引起各方广泛关注&#xff0c;已有部分企业员工使用ChatGPT等工具开展工作。但是&am…

带你系统的认识CHATGPT

近期CHATGPT火遍全球,各行各业的顶尖人才都在讨论着CHATGPT的发展趋势,中产们都研究着怎么使用CHATGPT产生更大的价值 今天我带大家系统的认识一下CHATGPT. 要说到CHATGPT,我们不得不先介绍一下OPENAI,它是一家人工智能研发公司,CHATGPT是它旗下的产品. OPENAI目前开放的产品有…

与chatGPT神聊,引领你深入浅出系统调用

在操作系统的教学中&#xff0c;系统调用的作用不言而喻&#xff0c;但是&#xff0c;对系统调用常常是雾里看花&#xff0c;似乎明白&#xff0c;又难以真正的触及&#xff0c;即使在代码中调用了系统调用&#xff0c;比如调用fork&#xff08;&#xff09;创建进程&#xff0…

从零开始开发自己的chatgpt平台 之 SSE(Server-Sent Events)客户端和服务端

提示&#xff1a;如果你认为本文对你有帮助&#xff0c;请点一下关注&#xff0c;后面会有更多人工智能方面的文章。 文章目录 前言一、SSE是什么&#xff1f;二、SSE服务端三、客户端四、SSE双向通信总结 如果有问题可以联系我**&#xff1a;https://gitee.com/xiaoyuren/gpt3…

中国院士称“我国已具备 ChatGPT 发展基础”

中国工程院院士王坚称「我国已具备支撑 ChatGPT 发展的算力基础」&#xff0c;“解好电力行业的关键问题&#xff0c;有可能会引领下一波AI浪潮。”中国工程院院士、阿里云icon创始人王坚2月17日在南方电网总部参加第四届电力调度AI应用大赛时表示。 我认为要开发出chatGPT这样…

Prompt 用法大全!让 ChatGPT 更智能的六种策略(中)

如果遵循以下六种策略来构建 Prompt 提示词&#xff0c;在和 ChatGPT 对话中我们将获得更好、更符合我们要求的回答。 这些策略&#xff0c;后几种更适合在编程调用 ChatGPT API 时使用&#xff0c;不过也适用直接和 ChatGPT 对话&#xff0c;让它更好的理解我们的意图。 1、写…

ChatGPT迎来华人产品负责人Peter Deng

6月1日&#xff0c;ChatGPT新任产品负责人Peter Deng在领英发布动态&#xff0c;宣布正式以“消费者产品副总裁”的身份加入了OpenAI&#xff0c;他写道&#xff0c;“我很高兴能够领导ChatGPT背后杰出的产品、设计和工程团队&#xff0c;目标是让AI对每个人都有用、易获得且有…

第十四届大学生服务外包创新创业大赛总结和心得

前言 比赛已经过去一个多月了&#xff0c;但是当时在为数不多的时间里学东西和完成项目的场景还历历在目&#xff0c;最后我们也获得了省三等的成绩&#xff0c;这对我们五个大一的学生来说已经非常满足了。 比赛介绍 相关连接&#xff1a;服务外包网址 比赛内容&#xff1a…

年薪高达 267 万元,ChatGPT 催生高薪职业,无需编程背景

整理 | 朱珂欣 出品 | CSDN程序人生&#xff08;ID&#xff1a;coder_life&#xff09; ChatGPT 的兴起&#xff0c;催生了一个“与众不同”的新职业 —— prompt engineer &#xff08;提示工程师&#xff09;。 主要职责是负责为 AI 聊天机器人生成的文本、图片、音频等内…

【关于ChatGPT的30个问题】25、ChatGPT的性能和效果如何?/ By 禅与计算机程序设计艺术

25、ChatGPT的性能和效果如何? 目录 25、ChatGPT的性能和效果如何? ChatGPT的性能涉及的方面 语言模型

ChatGPT专业应用:生成奖项方案

正文共 925 字&#xff0c;阅读大约需要 4 分钟 人力资源等必备技巧&#xff0c;您将在4分钟后获得以下超能力&#xff1a; 生成奖项方案 Beezy评级 &#xff1a;A级 *经过寻找和一段时间的学习&#xff0c;一部分人能掌握。主要提升效率并增强自身技能。 推荐人 | Kim 编辑者…

部署AI平台 宝马集团正在掀起新一轮数字化改革浪潮

数字化转型作为当代企业创新求变的重要突破口&#xff0c;成为各行各业推进持续发展的大热趋势。但在企业的在数字化征程中&#xff0c;却暗藏多重陷阱&#xff0c;数据孤岛、标准不一、质量太差、治理滞后、安全隐患等挑战&#xff0c;如影随形。 近日&#xff0c;宝马集团宣…

读书思考:步步惊心的《技术陷阱》

《技术陷阱》这本书450页&#xff0c;43万字之巨&#xff0c;信息量密密麻麻&#xff0c;采集的资料极其丰富&#xff0c;复习了一遍大停滞、大分流、大平衡、大逆转时代&#xff0c;并展望未来。 看完了有很多想法&#xff0c;随手写了下来&#xff0c;希望不是蹭热点。 &…