最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文解決Java中IP地址訪問HTTPS接口的SSL證書驗證問題

 更新時間:2025年12月19日 08:33:05   作者:一勺菠蘿丶  
這篇文章主要為大家詳細介紹了解決Java中IP地址訪問HTTPS接口的SSL證書驗證問題的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

問題描述

在使用Java的RestTemplate訪問HTTPS接口時,如果使用IP地址而不是域名,經常會遇到以下錯誤:

java.security.cert.CertificateException: No subject alternative names matching IP address 111.63.81.79 found
nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 111.63.81.79 found

奇怪的是:使用Postman、curl等工具可以正常訪問,但Java代碼卻報錯。

問題原因

SSL證書驗證機制

HTTPS協(xié)議在建立連接時,會進行SSL證書驗證,主要包括兩個方面:

  • 證書有效性驗證:檢查證書是否過期、是否被吊銷等
  • 主機名驗證:檢查證書中的域名或IP地址是否與訪問的地址匹配

為什么Postman可以,Java不行

  • Postman:默認情況下,Postman可能會跳過某些SSL驗證(特別是開發(fā)環(huán)境)
  • Java:Java的SSL驗證非常嚴格,會檢查證書的Subject Alternative Names (SAN)字段
  • 問題根源:當使用IP地址訪問時,如果證書的SAN中沒有包含該IP地址,Java就會拒絕連接

證書的Subject Alternative Names

SSL證書中有一個字段叫Subject Alternative Names (SAN),它列出了該證書可以用于哪些域名或IP地址。例如:

Subject Alternative Names:
    DNS: example.com
    DNS: www.example.com
    IP Address: 192.168.1.1

如果證書中沒有包含你訪問的IP地址(如111.63.81.79),Java就會拋出上述異常。

解決方案

方案概述

我們需要配置RestTemplate,讓它跳過SSL證書驗證。注意:這種方法只適用于開發(fā)/測試環(huán)境,生產環(huán)境應該使用正確的證書。

完整代碼實現

創(chuàng)建一個RestTemplateConfig配置類:

package com.example.zbx.config;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

/**
 * RestTemplate配置類
 * 配置忽略SSL證書驗證,支持使用IP地址訪問HTTPS接口
 * @author lxy
 */
@Configuration
public class RestTemplateConfig {

    /**
     * 創(chuàng)建RestTemplate Bean
     * 配置忽略SSL證書驗證,支持使用IP地址訪問HTTPS接口
     * @return RestTemplate實例
     */
    @Bean
    public RestTemplate restTemplate() {
        try {
            // 創(chuàng)建完全信任所有證書的TrustManager
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }

                        @Override
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                            // 不進行任何檢查,信任所有客戶端證書
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                            // 不進行任何檢查,信任所有服務器證書
                        }
                    }
            };

            // 創(chuàng)建SSL上下文,使用自定義的TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // 創(chuàng)建SSL連接工廠,忽略主機名驗證(包括IP地址驗證)
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
                    sslContext,
                    NoopHostnameVerifier.INSTANCE
            );

            // 創(chuàng)建請求配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(10000)  // 連接超時10秒
                    .setConnectionRequestTimeout(10000)  // 請求超時10秒
                    .setSocketTimeout(30000)  // 讀取超時30秒
                    .build();

            // 創(chuàng)建HttpClient
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(sslSocketFactory)
                    .setDefaultRequestConfig(requestConfig)
                    .evictExpiredConnections()
                    .evictIdleConnections(30, java.util.concurrent.TimeUnit.SECONDS)
                    .build();

            // 創(chuàng)建請求工廠
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setHttpClient(httpClient);
            factory.setConnectTimeout(10000);
            factory.setConnectionRequestTimeout(10000);
            factory.setReadTimeout(30000);

            // 創(chuàng)建RestTemplate
            return new RestTemplate(factory);
        } catch (Exception e) {
            throw new RuntimeException("創(chuàng)建RestTemplate失敗", e);
        }
    }
}

關鍵點說明

1. 自定義TrustManager

TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {
        @Override
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
            // 不進行任何檢查,信任所有服務器證書
        }
        // ... 其他方法
    }
};

這個X509TrustManager會跳過所有證書驗證,包括:

  • 證書是否過期
  • 證書是否被吊銷
  • 證書的域名/IP是否匹配

2. 創(chuàng)建SSL上下文

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

使用自定義的TrustManager初始化SSL上下文。

3. 忽略主機名驗證

SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
    sslContext,
    NoopHostnameVerifier.INSTANCE  // 不驗證主機名
);

NoopHostnameVerifier.INSTANCE會跳過主機名驗證,這樣即使證書中沒有對應的IP地址也能通過驗證。

Maven依賴

確保你的pom.xml中包含以下依賴:

<!-- HttpClient4 (for RestTemplate SSL configuration) -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

使用示例

配置完成后,直接使用RestTemplate即可,無需額外代碼:

@Autowired
private RestTemplate restTemplate;

public void callApi() {
    String url = "https://111.63.81.79:10091/api/endpoint";
    ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
    // 處理響應...
}

注意事項

安全警告

  • 僅用于開發(fā)/測試環(huán)境:跳過SSL驗證會帶來安全風險,生產環(huán)境不應該使用
  • 中間人攻擊風險:攻擊者可以偽造證書,你的應用無法識別
  • 數據泄露風險:無法保證連接的安全性

生產環(huán)境建議

如果必須在生產環(huán)境使用,建議:

  • 使用正確的證書:讓服務器提供包含IP地址的證書
  • 配置證書信任:只信任特定的證書頒發(fā)機構(CA)
  • 使用域名訪問:盡量使用域名而不是IP地址

示例:生產環(huán)境的正確做法

// 只信任特定的證書
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("truststore.jks"), "password".toCharArray());

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
trustManagerFactory.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

常見問題

Q1: 為什么之前可以,現在不行了?

可能的原因:

  • Java版本更新,SSL驗證更嚴格了
  • 服務器證書更新了,新證書沒有包含IP地址
  • 網絡環(huán)境變化,使用了不同的IP地址

Q2: 有沒有更簡單的辦法?

對于開發(fā)環(huán)境,可以設置JVM參數(不推薦):

-Dcom.sun.net.ssl.checkRevocation=false

但這種方法不夠靈活,建議使用配置類的方式。

Q3: 會影響其他HTTP請求嗎?

不會。這個配置只影響使用RestTemplate的HTTPS請求,HTTP請求不受影響。

Q4: 如何驗證配置是否生效?

在代碼中添加日志,觀察是否還有證書驗證錯誤:

log.info("RestTemplate配置完成,SSL驗證已禁用");

如果不再出現CertificateException,說明配置生效了。

總結

  • 問題根源:Java的SSL驗證嚴格,證書中沒有IP地址時會拒絕連接
  • 解決方案:配置RestTemplate跳過SSL證書驗證
  • 關鍵代碼:自定義X509TrustManager + NoopHostnameVerifier
  • 安全提醒:僅用于開發(fā)/測試環(huán)境,生產環(huán)境應使用正確的證書

到此這篇關于一文解決Java中IP地址訪問HTTPS接口的SSL證書驗證問題的文章就介紹到這了,更多相關Java解決SSL證書驗證問題內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mybatis遷移到Mybatis-Plus的實現方法

    Mybatis遷移到Mybatis-Plus的實現方法

    這篇文章主要介紹了Mybatis遷移到Mybatis-Plus的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • 如何基于LoadingCache實現Java本地緩存

    如何基于LoadingCache實現Java本地緩存

    這篇文章主要介紹了如何基于LoadingCache實現Java本地緩存,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • idea本地merge如何合并代碼

    idea本地merge如何合并代碼

    這篇文章主要介紹了idea本地merge如何合并代碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java從控制臺接受輸入字符的簡單方法

    Java從控制臺接受輸入字符的簡單方法

    這篇文章主要介紹了Java從控制臺接受輸入字符的簡單方法,需要的朋友可以參考下
    2014-02-02
  • SpringBoot如何接收前端傳遞參數

    SpringBoot如何接收前端傳遞參數

    這篇文章主要介紹了SpringBoot如何接收前端傳遞參數,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-08-08
  • Java壓縮文件為ZIP并加密的詳細步驟

    Java壓縮文件為ZIP并加密的詳細步驟

    Zip是一種常用的文件壓縮格式,下面這篇文章主要給大家介紹了關于Java壓縮文件為ZIP并加密的詳細步驟,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • Java平閏年判斷的方法總結

    Java平閏年判斷的方法總結

    本篇文章給大家整理了Java平閏年判斷的兩種方法,大家在寫程序的時候如果用的到參考下吧。
    2018-02-02
  • Java中跨域問題解決的幾種方式舉例詳解

    Java中跨域問題解決的幾種方式舉例詳解

    這篇文章主要介紹了前后端分離項目中跨域問題的解決方法,包括設置響應頭信息、使用iframe、WebSocket、HttpServletResponse添加頭信息以及通過配置類等多種方式,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-12-12
  • EditPlus運行java時從鍵盤輸入數據的操作方法

    EditPlus運行java時從鍵盤輸入數據的操作方法

    這篇文章主要介紹了EditPlus運行java時從鍵盤輸入數據的操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java中的static關鍵字用法總結

    Java中的static關鍵字用法總結

    這篇文章主要介紹了Java中的static關鍵字用法總結,static是Java50個關鍵字之一,static關鍵字可以用來修飾代碼塊表示靜態(tài)代碼塊,修飾成員變量表示全局靜態(tài)成員變量,修飾方法表示靜態(tài)方法,需要的朋友可以參考下
    2023-11-11

最新評論

莎车县| 桑日县| 卓资县| 客服| 安泽县| 九寨沟县| 云浮市| 甘谷县| 隆化县| 湾仔区| 河间市| 东莞市| 奎屯市| 青浦区| 敖汉旗| 灯塔市| 孝义市| 邵阳市| 兴国县| 响水县| 林西县| 彭州市| 兰溪市| 晋中市| 麻栗坡县| 武隆县| 三台县| 巨野县| 二连浩特市| 清水县| 左云县| 得荣县| 无锡市| 齐齐哈尔市| 富民县| 佳木斯市| 台北市| 株洲市| 津南区| 固始县| 芷江|