ssl Retrofit不支持CLEARTEXT通信

svgewumm  于 2023-10-19  发布在  其他
关注(0)|答案(6)|浏览(153)

我试图连接到https服务器上的android使用Retrofit.这是我的OkHttpClient

@Provides
public OkHttpClient provideContactClient(){
  HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
  ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
      .tlsVersions(TlsVersion.TLS_1_2)
      .cipherSuites(CipherSuite.TLS_RSA_WITH_DES_CBC_SHA,
          CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
          CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
      .build();
  interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
  SSLSocketFactory sslSocketFactory = null;
  try {
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, null, null);
    sslSocketFactory = sslContext.getSocketFactory();
  }catch (GeneralSecurityException e){
    e.printStackTrace();
  }
  return new OkHttpClient.Builder()
      .addInterceptor(interceptor)
      .connectionSpecs(Collections.singletonList(spec))
      .sslSocketFactory(sslSocketFactory)
      .authenticator(new Authenticator() {
        @Override
        public Request authenticate(Route route, Response response) throws IOException {
          if(responseCount(response) >= 5){
            return null;
          }
          String credential = Credentials.basic("user", "pass");
          return response.request().newBuilder().header("Authorization", credential).build();
        }
      })
      .build();
}

但是我一直收到CLEARTEXT communication not supported:异常
在调试RealConnection类时,我注意到route.address()成员没有sslSocketFactory,尽管它在Bulider中被分配。

dly7yett

dly7yett1#

根据网络安全配置

本节中的指导仅适用于面向Android 8.1(API级别27)或更低版本的应用。从Android 9(API级别28)开始,默认情况下将禁用明文支持。

创建文件res/xml/network_security_login.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
    </domain-config>
</network-security-config>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
</manifest>

或者你可以直接在manifest中设置。

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>
rnmwe5a2

rnmwe5a22#

仅将此添加到manifest(在应用程序内部)

android:usesCleartextTraffic="true"

工作!

avkwfej4

avkwfej43#

CLEARTEXT消息是由于直接或通过服务器端重定向(例如,以https开始,然后重定向到http)请求http URL。
在您的“未找到证书路径的信任锚”消息方面,您的服务器似乎正在使用一些SSL证书,这些证书没有得到您正在测试的任何Android环境中的标准证书的支持。例如,您的服务器可能正在使用自签名SSL证书。
选项包括:

jckbn6z7

jckbn6z74#

也“CLEARTEXT通信不支持异常”可能很容易产生,即使在旧的Android设备(6.0,5.0,5.1等)通过OkHttp库,如果你要求一个https://主机/TLS ConnectionSpec设置.

wnavrhmk

wnavrhmk5#

usesCleartextTraffic
在manifest.xml文件中使用tools:replace=“android:usesCleartextTraffic”

zxlwwiss

zxlwwiss6#

您遇到的错误消息“192.168.0.107网络安全策略不允许与www.example.com进行CLEARTEXT通信”表示您的Android应用正尝试通过未加密连接(HTTP)而不是加密连接(HTTPS)与服务器(192.168.0.107)进行通信。从Android 9(Pie)开始,Android的网络安全策略默认强制执行安全通信,并且不允许未加密的流量。
要解决此问题,您有以下几种选择:
使用HTTPS:最安全的选择是将服务器配置为使用HTTPS(SSL/TLS)。这涉及到为您的服务器获取SSL证书,并配置您的Web服务器软件(例如Apache,Nginx)以使用SSL。使用HTTPS设置服务器后,您可以从Android应用安全地与其通信。
网络安全配置:如果出于开发或测试目的需要与不安全的服务器进行通信,则可以创建网络安全配置文件,以允许明文通信到达特定域或IP地址。这应该只用于开发,不建议用于生产。
在Android项目的res/xml目录中创建一个网络安全配置XML文件(例如,network_security_log.xml):

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

然后,在AndroidManifest.xml中引用此配置:

<application
    android:networkSecurityConfig="@xml/network_security_config"
    ...
>

使用这种方法时要谨慎,不要在生产环境中使用它。
使用Android较低版本的模拟器或设备:如果您在Android 8.0(Oreo)或更低版本的物理设备或模拟器上运行应用,则不会遇到此问题,因为它们不会像较新的Android版本那样强制执行网络安全策略。然而,这不是一个建议的长期解决方案,因为它没有解决潜在的安全问题。
对于生产环境,您应该始终使用HTTPS(选项1)。应尽可能避免不安全的通信,以保护数据传输并保持安全性。

相关问题