javax.net.ssl.SSLHandshakeException[Security:090476]Invalid/unknown SSL

在处理服务器请求时遇到了未捕获的异常,具体为SSL握手异常。错误详细信息显示,从K8S-T03-192.168.149.13收到的SSL头部无效或未知,导致SSL握手失败。该问题可能与网络安全、证书配置或TLS连接有关。

<Aug 5, 2021 8:59:04 PM> <WARNING> <Uncaught exception in server handlerjavax.net.ssl.SSLHandshakeException: [Security:090476]Invalid/unknown SSL header was received from peer K8S-T03 - 192.168.149.13 during SSL handshake.>
javax.net.ssl.SSLHandshakeException: [Security:090476]Invalid/unknown SSL header was received from peer K8S-T03 - 192.168.149.13 during SSL handshake.
        at com.certicom.tls.interfaceimpl.TLSConnectionImpl.fireException(Unknown Source)
        at com.certicom.tls.interfaceimpl.TLSConnectionImpl.fireAlertSent(Unknown Source)
        at com.certicom.tls.record.ReadHandler.fireAlert(Unknown Source)
        at com.certicom.tls.record.ReadHandler.getProtocolVersion(Unknown Source)
        at com.certicom.tls.record.ReadHandler.checkVersion(Unknown Source)
        at com.certicom.tls.record.ReadHandler.readRecord(Unknown Source)
        at com.certicom.tls.record.ReadHandler.readUntilHandshakeComplete(Unknown Source)
        at com.certicom.tls.interfaceimpl.TLSConnectionImpl.completeHandshake(Unknown Source)
        at com.certicom.tls.record.ReadHandler.read(Unknown Source)
        at com.certicom.io.InputSSLIOStreamWrapper.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at weblogic.nodemanager.server.Handler.run(Handler.java:71)
        at java.lang.Thread.run(Thread.java:748)
 

==================

/app/weblogic/Oracle/Middleware/wlserver_10.3/common/nodemanager/nodemanager.properties

#SecureListener=true
SecureListener=false
 

 

 

2025-06-10 23:59:24.729 30065-4066 DataLoader com.example.kucun2 E Failed to load data javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:356) at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1127) at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1082) at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:869) at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:740) at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:705) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:896) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.-$$Nest$mprocessDataFromSocket(Unknown Source:0) at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:236) at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:218) at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379) at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337) at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74) at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255) <string name="url">https://192.168.31.177:3000</string> <string name="url_all">/app/all</string> <string name="url_bancis">/app/bancai/all</string> <string name="url_caizhis">/app/caizhi/all</string> <string name="url_mupis">/app/mupi/all</string> <string name="url_dingdans">/app/dingdan/all</string> <string name="url_chanpins">/app/chanpin/all</string> <string name="url_zujians">/app/zujian/all</string> <string name="url_chanpin_zujians">/app/chanpin_zujian/all</string> <string name="url_dingdan_zujians">/app/dingdan_zujian/all</string> <string name="url_dingdan_chanpins">/app/dingdan_chanpin/all</string> <string name="url_jinhuos">/app/jinhuo/all</string> <string name="url_add_bancai">/app/bancai/add</string> <string name="url_add_dingdan">/app/dingdan/add</string> <string name="url_add_chanpin">/app/chanpin/add</string> <string name="url_add_zujian">/app/zujian/add</string> <string name="url_add_caizhi">/app/caizhi/add</string> <string name="url_add_mupi">/app/mupi/add</string> <string name="url_add_dingdan_chanpin">/app/dingdan_chanpi/add</string> <string name="url_add_dingdan_zujian">/app/dingdan_zujian/add</string> <string name="url_add_chanpin_zujian">/app/chanpin_zujian/add</string> <string name="url_add_jinhuo">/app/jinhuo/add</string> package com.example.kucun2.entity.data; import android.content.Context; import android.util.Log; import com.example.kucun2.entity.*; import com.example.kucun2.function.MyAppFnction; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.lang.reflect.Type; import java.util.*; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class Data { // 数据集合声明(保持原有属性名不变) public static SynchronizedList<Bancai> bancais = new SynchronizedList<>(Bancai.class); public static SynchronizedList<Caizhi> caizhis = new SynchronizedList<>(Caizhi.class); public static SynchronizedList<Mupi> mupis = new SynchronizedList<>(Mupi.class); public static SynchronizedList<Chanpin> chanpins = new SynchronizedList<>(Chanpin.class); public static SynchronizedList<Chanpin_Zujian> chanpinZujians = new SynchronizedList<>(Chanpin_Zujian.class); public static SynchronizedList<Dingdan> dingdans = new SynchronizedList<>(Dingdan.class); public static SynchronizedList<Dingdan_Chanpin> dingdanChanpins = new SynchronizedList<>(Dingdan_Chanpin.class); public static SynchronizedList<Dingdan_chanpin_zujian> dingdanBancais = new SynchronizedList<>(Dingdan_chanpin_zujian.class); public static SynchronizedList<Kucun> kucuns = new SynchronizedList<>(Kucun.class); public static SynchronizedList<Zujian> zujians = new SynchronizedList<>(Zujian.class); public static SynchronizedList<User> users = new SynchronizedList<>(Bancai.class); public static SynchronizedList<Jinhuo> jinhuoList = new SynchronizedList<>(Bancai.class); private static final Gson gson = new Gson(); private static final OkHttpClient client = new OkHttpClient(); private static final String TAG = "DataLoader"; // 加载所有数据的方法 public static void loadAllData(Context context, LoadDataCallback callback) { String url = MyAppFnction.getStringResource("string", "url") + MyAppFnction.getStringResource("string", "url_all"); Log.d("url", "loadAllData: "+url); Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "Failed to load data", e); if (callback != null) callback.onFailure(); } @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) { Log.e(TAG, "Unexpected response code: " + response.code()); if (callback != null) callback.onFailure(); return; } String responseData = response.body().string(); parseAndAssignData(responseData, context, callback); } }); } // 解析并赋值数据 private static void parseAndAssignData(String jsonData, Context context, LoadDataCallback callback) { // 创建包含所有数据类型的TypeToken Type informationType = new TypeToken<Information<AllDataResponse>>(){}.getType(); Information<AllDataResponse> information = gson.fromJson(jsonData, informationType); if (information == null || information.getData() == null || information.getStatus() != 200) { Log.e(TAG, "Invalid response data"); if (callback != null) callback.onFailure(); return; } AllDataResponse allData = information.getData(); // 赋值到对应的列表(使用安全方法保持已有引用) updateList(bancais, allData.bancais); updateList(caizhis, allData.caizhis); updateList(mupis, allData.mupis); updateList(chanpins, allData.chanpins); updateList(chanpinZujians, allData.chanpin_zujians); updateList(dingdans, allData.dingdans); updateList(dingdanChanpins, allData.dingdan_chanpins); updateList(dingdanBancais, allData.dingdan_bancais); updateList(kucuns, allData.kucuns); updateList(zujians, allData.zujians); updateList(users, allData.users); updateList(jinhuoList, allData.jinhuos); resolveReferences(); if (callback != null) callback.onSuccess(); } // 更新列表内容但保持对象引用不变 private static <T> void updateList(List<T> existingList, List<T> newList) { if (newList == null) return; existingList.clear(); existingList.addAll(newList); } // 解析对象间的引用关系(使用ID关联) private static void resolveReferences() { // 创建ID到对象的映射 Map<Integer, Bancai> bancaiMap = createIdMap(bancais); Map<Integer, Caizhi> caizhiMap = createIdMap(caizhis); Map<Integer, Mupi> mupiMap = createIdMap(mupis); Map<Integer, Chanpin> chanpinMap = createIdMap(chanpins); Map<Integer, Zujian> zujianMap = createIdMap(zujians); Map<Integer, Dingdan> dingdanMap = createIdMap(dingdans); Map<Integer, Kucun> kucunMap = createIdMap(kucuns); // 解析Bancai引用 for (Bancai bancai : bancais) { if (bancai.getCaizhi() != null) { bancai.setCaizhi(caizhiMap.get(bancai.getCaizhi().getId())); } if (bancai.getMupi1() != null) { bancai.setMupi1(mupiMap.get(bancai.getMupi1().getId())); } if (bancai.getMupi2() != null) { bancai.setMupi2(mupiMap.get(bancai.getMupi2().getId())); } } // 解析Kucun引用 for (Kucun kucun : kucuns) { if (kucun.getBancai() != null) { kucun.setBancai(bancaiMap.get(kucun.getBancai().getId())); } } // 解析订单相关的嵌套对象 for (Dingdan_Chanpin dc : dingdanChanpins) { if (dc.getDingdan() != null) { dc.setDingdan(dingdanMap.get(dc.getDingdan().getId())); } if (dc.getChanpin() != null) { dc.setChanpin(chanpinMap.get(dc.getChanpin().getId())); } } // 解析产品相关的嵌套对象 for (Chanpin_Zujian cz : chanpinZujians) { if (cz.getChanpin() != null) { cz.setChanpin(chanpinMap.get(cz.getChanpin().getId())); } if (cz.getZujian() != null) { cz.setZujian(zujianMap.get(cz.getZujian().getId())); } if (cz.getBancai() != null) { cz.setBancai(bancaiMap.get(cz.getBancai().getId())); } } // 解析库存关联 for (Kucun k : kucuns) { if (k.getBancai() != null) { k.setBancai(bancaiMap.get(k.getBancai().getId())); } } } // 创建ID到对象的映射 private static <T extends EntityClassGrassrootsid> Map<Integer, T> createIdMap(List<T> list) { Map<Integer, T> map = new HashMap<>(); for (T item : list) { map.put(item.getId(), item); } return map; } // 回调接口 public interface LoadDataCallback { void onSuccess(); void onFailure(); } // 内部类用于解析JSON响应 public static class AllDataResponse { public List<Bancai> bancais; public List<Caizhi> caizhis; public List<Mupi> mupis; public List<Chanpin> chanpins; public List<Chanpin_Zujian> chanpin_zujians; public List<Dingdan> dingdans; public List<Dingdan_Chanpin> dingdan_chanpins; public List<Dingdan_chanpin_zujian> dingdan_bancais; public List<Kucun> kucuns; public List<Zujian> zujians; public List<User> users; public List<Jinhuo> jinhuos; } }
最新发布
06-12
<think>我们遇到的问题是一个Android应用在加载数据时发生了SSLHandshakeException,具体原因是“Trustanchorforcertificationpathnotfound”。这通常发生在尝试使用HTTPS连接时,服务器的证书未被设备信任(例如自签名证书或未由受信任CA签名的证书)。错误日志中还显示了服务器地址:https://192.168.31.177:3000,这是一个本地IP地址,很可能使用的是自签名证书。解决方案:1.添加网络安全配置(针对Android7.0及以上)2.创建自定义的信任管理器,接受所有证书(不推荐用于生产环境,仅适用于开发或内部测试)3.使用OkHttp的自定义SSL配置步骤:第一步:创建网络安全配置文件在res/xml目录下创建文件network_security_config.xml,内容如下:```xml<?xmlversion="1.0"encoding="utf-8"?><network-security-config><domain-configcleartextTrafficPermitted="false"><domainincludeSubdomains="true">192.168.31.177</domain><!--或者使用通配符配置--><trust-anchors><certificatessrc="@raw/my_ca"/><!--如果你有自签名证书的CA,放在raw文件夹下--><certificatessrc="system"/><!--系统证书--><certificatessrc="user"/><!--用户证书--></trust-anchors></domain-config><!--如果不想区分域名,可以使用base-config--><!--注意:以下配置会信任所有证书,包括自签名证书,不安全,仅用于开发测试--><!--<base-configcleartextTrafficPermitted="false"><trust-anchors><certificatessrc="system"/><certificatessrc="user"/></trust-anchors></base-config>--></network-security-config>```第二步:在AndroidManifest.xml中应用网络安全配置在<application>标签中添加:android:networkSecurityConfig="@xml/network_security_config"第三步:如果第一步中使用了自定义CA证书(my_ca),请将自签名证书文件(.crt或.pem格式)放在res/raw目录下。但是,对于开发阶段,我们可能没有CA证书,或者希望暂时信任所有证书。我们可以使用OkHttp的自定义信任管理器。使用OkHttp自定义信任管理器(忽略证书验证):注意:这种方法会忽略所有的SSL证书验证,存在安全风险,只应在开发和测试环境中使用。修改Data类中的OkHttpClient初始化代码:首先,创建一个忽略证书验证的TrustManager:然后,在Data类中创建一个忽略证书的OkHttpClient实例。具体代码修改如下:在Data类中修改client的初始化:将原来的:privatestaticfinalOkHttpClientclient=newOkHttpClient();改为:privatestaticfinalOkHttpClientclient=createUnsafeOkHttpClient();然后,添加一个方法createUnsafeOkHttpClient():但是注意:由于我们使用了SynchronizedList等自定义类,以及回调,所以需要确保这个修改不会引起其他问题。以下是创建忽略证书验证的OkHttpClient的代码(不推荐用于生产环境):注意:需要导入相关的包。代码示例(在Data类中添加):```javaprivatestaticOkHttpClientcreateUnsafeOkHttpClient(){try{//创建信任所有证书的信任管理器finalTrustManager[]trustAllCerts=newTrustManager[]{newX509TrustManager(){@OverridepublicvoidcheckClientTrusted(java.security.cert.X509Certificate[]chain,StringauthType){}@OverridepublicvoidcheckServerTrusted(java.security.cert.X509Certificate[]chain,StringauthType){}@Overridepublicjava.security.cert.X509Certificate[]getAcceptedIssuers(){returnnewjava.security.cert.X509Certificate[]{};}}};//安装信任管理器finalSSLContextsslContext=SSLContext.getInstance("SSL");sslContext.init(null,trustAllCerts,newjava.security.SecureRandom());//创建SSLSocketFactoryfinalSSLSocketFactorysslSocketFactory=sslContext.getSocketFactory();OkHttpClient.Builderbuilder=newOkHttpClient.Builder();builder.sslSocketFactory(sslSocketFactory,(X509TrustManager)trustAllCerts[0]);builder.hostnameVerifier(newHostnameVerifier(){@Overridepublicbooleanverify(Stringhostname,SSLSessionsession){returntrue;//验证主机名,直接返回true表示接受}});returnbuilder.build();}catch(Exceptione){thrownewRuntimeException(e);}}```这样修改后,OkHttpClient将信任所有证书,包括自签名证书。但是,请注意:在生产环境中,应该使用受信任的证书,避免使用上述方法。另外,日志中还显示我们访问的URL是IP地址(192.168.31.177),而通常证书是绑定域名的,所以即使我们信任了证书,也可能因为主机名不匹配而失败(例如证书里是域名而我们是IP)。因此,我们还需要在hostnameVerifier中接受所有主机名(如上面的代码所示,直接返回true)。总结:上述修改后,应该能够解决SSLHandshakeException问题。但是,我们也要注意,这个修改会忽略所有的SSL验证,包括主机名验证。在生产环境中,我们应该使用正确的证书配置,或者只针对特定域名或IP进行配置。修改后的Data类(部分):我们将原来的client替换为通过createUnsafeOkHttpClient()方法创建的client。注意:需要添加的导入如下:```javaimportjavax.net.ssl.SSLContext;importjavax.net.ssl.SSLSession;importjavax.net.ssl.SSLSocketFactory;importjavax.net.ssl.TrustManager;importjavax.net.ssl.X509TrustManager;importokhttp3.OkHttpClient;```由于代码较长,这里只给出修改的部分。最后,如果服务器证书是自签名的,并且你希望在生产环境中使用,建议购买正规证书或使用Let'sEncrypt等免费证书,或者将自签名的CA证书安装到设备上。相关问题:1.如何为Android应用添加网络安全配置?2.如何在Android中信任自签名证书?3.OkHttp如何忽略SSL证书验证?4.在Android开发中如何处理SSLHandshakeException?根据您的要求,我们提出相关问题。</think> 根据提供的代码和日志,这是一个典型的 **SSL 证书验证失败**问题。你的 Android 应用尝试连接到 `https://192.168.31.177:3000`,但设备不信任该服务器的 SSL 证书。 ### 问题分析 错误信息关键点: ``` SSLHandshakeException: Trust anchor for certification path not found ``` 原因: 1. 服务器使用自签名证书而非受信任 CA 颁发的证书 2. 证书域名/IP 不匹配(192.168.31.177 是内网 IP) 3. Android 默认不信任自签名证书 ### 解决方案 以下是三种解决方案(推荐方案1): #### 方案1:添加网络安全配置(推荐) **修改网络安全配置:** ```xml <!-- res/xml/network_security_config.xml --> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">192.168.31.177</domain> <trust-anchors> <certificates src="system"/> <certificates src="user"/> <!-- 允许用户安装的证书 --> </trust-anchors> </domain-config> </network-security-config> ``` **AndroidManifest.xml 中添加配置:** ```diff <application ... + android:networkSecurityConfig="@xml/network_security_config" ...> ``` **将服务器证书安装到设备:** 1. 获取服务器证书文件(.crt 或 .pem) 2. 在 Android 设置中安装证书:"设置" → "安全" → "加密与凭证" → "安装证书" #### 方案2:在代码中忽略 SSL 验证(测试环境使用) ```java // Data.java 中添加 import javax.net.ssl.*; import okhttp3.OkHttpClient; // 创建信任所有证书的 OkHttpClient private static OkHttpClient getUnsafeOkHttpClient() { try { final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {} @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } } }; final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); return new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]) .hostnameVerifier((hostname, session) -> true) // 忽略主机名验证 .build(); } catch (Exception e) { throw new RuntimeException(e); } } ``` **修改 loadAllData 方法:** ```java public static void loadAllData(...) { // 使用自定义的忽略SSL验证的client OkHttpClient unsafeClient = getUnsafeOkHttpClient(); Request request = new Request.Builder() .url(url) .build(); unsafeClient.newCall(request).enqueue(...); // 使用自定义client } ``` #### 方案3:使用 HTTP 代替 HTTPS(仅开发环境) ```xml <!-- res/values/strings.xml --> <string name="url">http://192.168.31.177:3000</string> <!-- HTTP 协议 --> ``` **AndroidManifest.xml 中允许明文传输:** ```diff <application ... + android:usesCleartextTraffic="true" ...> ``` ### 最佳实践建议 1. **开发环境**:使用方案2的代码方式快速解决 2. **生产环境**:使用方案1安装正式CA证书 3. **本地测试**:使用HTTP(方案3)最便捷但最不安全 4. **长期方案**:为服务器申请免费SSL证书(Let's Encrypt) ### 证书验证流程图 ```mermaid graph TD A[发起 HTTPS 请求] --> B{证书是否受信任?} B -- 是 --> C[正常通信] B -- 否 --> D[抛出 SSLHandshakeException] D --> E[方案1 添加证书信任] D --> F[方案2 代码跳过验证] D --> G[方案3 改用HTTP] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值