未找到 Android SSL 连接的信任锚

发布于 2024-11-26 03:53:33 字数 536 浏览 2 评论 0 原文

我正在尝试连接到运行 godaddy 256 位 SSL 证书的 IIS6 机器,但收到错误:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

一直在尝试确定可能导致该问题的原因,但现在绘制空白。

这是我的连接方式:

HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());

I am trying to connect to an IIS6 box running a godaddy 256bit SSL cert, and I am getting the error :

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Been trying to determine what could be causing that, but drawing blanks right now.

Here is how I am connecting :

HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(23

迷鸟归林 2024-12-03 03:53:33

与接受的答案相反,您不需要需要自定义信任管理器,您需要修复服务器配置!

在连接到 Apache 服务器时,我遇到了同样的问题,并且未正确安装 dynadot/alphassl 证书。我正在使用 HttpsUrlConnection (Java/Android) 进行连接,该连接抛出异常 -

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

实际问题是服务器配置错误 - 使用 http://www.digicert.com/help/ 或类似的,它甚至会告诉你解决方案:

“该证书不是由受信任的机构签名的(检查 Mozilla 的根存储)。如果你购买了证书来自一个受信任的机构,您可能只需要安装一个或多个中间证书,请联系您的证书提供商以获取针对您的服务器平台执行此操作的帮助。”

您还可以使用 openssl 检查证书:

openssl s_client -debug -connect www.thedomaintocheck.com:443

您可能会看到:

验证返回代码:21(无法验证第一个证书) )

并且,在输出的前面:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

证书链将仅包含 1 个元素(您的证书):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

...但应将链中的签名权限引用回 Android 信任的签名权限(Verisign、 GlobalSign 等):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

配置服务器的说明(和中间证书)通常由颁发证书的机构提供,例如:http://www.alphassl.com/support/install-root-certificate.html

安装证书颁发者提供的中间证书后,我现在没有错误连接使用HttpsUrlConnection。

Contrary to the accepted answer you do not need a custom trust manager, you need to fix your server configuration!

I hit the same problem while connecting to an Apache server with an incorrectly installed dynadot/alphassl certificate. I'm connecting using HttpsUrlConnection (Java/Android), which was throwing -

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

The actual problem is a server misconfiguration - test it with http://www.digicert.com/help/ or similar, and it will even tell you the solution:

"The certificate is not signed by a trusted authority (checking against Mozilla's root store). If you bought the certificate from a trusted authority, you probably just need to install one or more Intermediate certificates. Contact your certificate provider for assistance doing this for your server platform."

You can also check the certificate with openssl:

openssl s_client -debug -connect www.thedomaintocheck.com:443

You'll probably see:

Verify return code: 21 (unable to verify the first certificate)

and, earlier in the output:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

The certificate chain will only contain 1 element (your certificate):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... but should reference the signing authorities in a chain back to one which is trusted by Android (Verisign, GlobalSign, etc):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

Instructions (and the intermediate certificates) for configuring your server are usually provided by the authority that issued your certificate, for example: http://www.alphassl.com/support/install-root-certificate.html

After installing the intermediate certificates provided by my certificate issuer I now have no errors when connecting using HttpsUrlConnection.

懒猫 2024-12-03 03:53:33

@Chrispix 的解决方案很危险! 信任所有证书允许任何人进行中间人攻击!只需将任何证书发送给客户端,客户端就会接受它!

将您的证书添加到自定义信任管理器,如本文所述:通过 HTTPS 使用 HttpClient 信任所有证书

虽然使用自定义证书建立安全连接有点复杂,但它会为您带来所需的 ssl 加密安全无中间人攻击的危险!

The solution of @Chrispix is dangerous! Trusting all certificates allows anybody to do a man in the middle attack! Just send ANY certificate to the client and it will accept it!

Add your certificate(s) to a custom trust manager like described in this post: Trusting all certificates using HttpClient over HTTPS

Although it is a bit more complex to establish a secure connection with a custom certificate, it will bring you the wanted ssl encryption security without the danger of man in the middle attack!

朮生 2024-12-03 03:53:33

根据最新 Android 文档进行更新(2017 年 3 月):

当您收到此类错误时:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

问题可能是以下原因之一:

  1. 颁发服务器证书的 CA 未知
  2. 服务器证书不是由 CA 签名,但是自签名
  3. 服务器配置缺少中间 CA

解决方案是教导 HttpsURLConnection 信任一组特定的 CA。如何?请检查 https://developer.android.com/training/articles/security -ssl.html#CommonProblems

其他使用 com.loopj.android:android-async-http 库中的 AsyncHTTPClient 的人,请检查设置 AsyncHttpClient 以使用 HTTPS

Update based on latest Android documentation (March 2017):

When you get this type of error:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

the issue could be one of the following:

  1. The CA that issued the server certificate was unknown
  2. The server certificate wasn't signed by a CA, but was self signed
  3. The server configuration is missing an intermediate CA

The solution is to teach HttpsURLConnection to trust a specific set of CAs. How? Please check https://developer.android.com/training/articles/security-ssl.html#CommonProblems

Others who are using AsyncHTTPClient from com.loopj.android:android-async-http library, please check Setup AsyncHttpClient to use HTTPS.

耀眼的星火 2024-12-03 03:53:33

您可以在运行时信任特定证书。
只需从服务器下载它,放入资产并使用 ssl-utils-android 加载:

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

在上面的示例中,我使用了 OkHttpClient,但 SSLContext 可以与 Java 中的任何客户端一起使用。

如果您有任何疑问,请随时提问。我是这个小图书馆的作者。

You can trust particular certificate at runtime.
Just download it from server, put in assets and load like this using ssl-utils-android:

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

In the example above I used OkHttpClient but SSLContext can be used with any client in Java.

If you have any questions feel free to ask. I'm the author of this small library.

剑心龙吟 2024-12-03 03:53:33

回复很旧的帖子。但也许它会对一些新手有所帮助,如果上述方法都不起作用的话。

解释:我知道没有人想要垃圾解释;而不是解决方案。但在一个班轮中,您正尝试从本地计算机访问不信任您计算机的远程计算机的服务。您请求需要获得远程服务器的信任。

解决方案:以下解决方案假设您满足以下条件:

  1. 尝试从本地计算机访问远程 api。
  2. 您正在构建 Android 应用程序
  3. 您的远程服务器处于代理过滤之下(您在浏览器设置中使用代理来访问远程 api 服务,通常是登台或开发服务器)
  4. 您正在真实设备上进行测试

步骤:

您需要一个 .keystore 扩展文件来注册您的应用程序。如果您不知道如何创建 .keystore 文件;然后按照以下创建 .keystore 文件部分进行操作,或者跳至下一部分签署 Apk 文件

创建 .keystore 文件

打开 Android Studio。单击顶部菜单“构建”>“构建”生成签名的 APK。在下一个窗口中,单击创建新...按钮。在新窗口中,请在所有字段中输入数据。请记住我建议的两个密码字段应该具有相同的密码;不要使用不同的密码;还要记住最顶部字段密钥存储路径:的保存路径。输入所有字段后,单击“确定”按钮。

签署 Apk 文件

现在您需要使用刚刚创建的 .keystore 文件构建一个签名的应用程序。按照以下步骤

  1. 进行构建>清理项目,等待它完成清理
  2. Build >生成签名的 APK
  3. 单击选择现有... 按钮
  4. 选择我们刚刚在创建 .keystore 文件部分中创建的 .keystore 文件
  5. 输入您在创建时创建的相同密码>创建 .keystore 文件部分。对密钥库密码密钥密码字段使用相同的密码。还要输入别名
  6. 单击“下一步”按钮
  7. 在下一个屏幕中;根据 build.gradle 文件中的设置可能会有所不同,您需要选择 Build TypesFlavors
  8. 对于 Build Types,从下拉列表中选择 release
  9. 对于 Flavors,但这取决于您在 build.gradle< 中的设置/代码> 文件。从此字段中选择暂存。我在 build.gradle 中使用了以下设置,您可以使用与我相同的设置,但请确保将 applicationId 更改为您的包名称

    产品风味 {
        分期{
            applicationId“com.yourapplication.package”
            manifestPlaceholders = [图标:“@drawable/ic_launcher”]
            buildConfigField "boolean", "CATALYST_DEBUG", "true"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true"
        }
        生产 {
            buildConfigField“布尔值”,“CATALYST_DEBUG”,“假”
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false"
        }
    }
    

  10. 单击底部两个 Signature Versions 复选框,然后单击 Finish 按钮。

即将完成:

所有的努力都已完成,现在是真理的运动。为了访问通过代理备份的临时服务器,您需要在实际测试的 Android 设备中进行一些设置。

Android 设备中的代理设置:

  1. 点击 Android 手机内的设置,然后点击 wi-fi
  2. 长按已连接的 wifi,然后选择修改网络
  3. 点击高级选项如果您看不到代理主机名字段,
  4. 请在代理主机名中输入您要连接的主机IP或名称。典型的登台服务器将命名为 stg.api.mygoodcompany.com
  5. 对于端口,输入四位数端口号,例如 9502
  6. 点击保存 > 按钮

最后一站:

请记住,我们在签署 APK 文件部分中生成了签名的 apk 文件。现在是时候安装该 APK 文件了。

  1. 打开终端并更改为签名的 apk 文件夹
  2. 将 Android 设备连接到您的计算机
  3. 从 Android 设备中删除任何以前安装的 apk 文件
  4. 运行 adb install apk 文件的名称
  5. 如果由于某种原因上述命令返回adb command not found。输入完整路径 C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe install apk 文件的名称

我希望问题能够得到解决。如果没有请给我留言。

萨拉姆!

Replying to very old post. But maybe it will help some newbie and if non of the above works out.

Explanation: I know nobody wants explanation crap; rather the solution. But in one liner, you are trying to access a service from your local machine to a remote machine which does not trust your machine. You request need to gain the trust from remote server.

Solution: The following solution assumes that you have the following conditions met

  1. Trying to access a remote api from your local machine.
  2. You are building for Android app
  3. Your remote server is under proxy filtration (you use proxy in your browser setting to access the remote api service, typically a staging or dev server)
  4. You are testing on real device

Steps:

You need a .keystore extension file to signup your app. If you don't know how to create .keystore file; then follow along with the following section Create .keystore file or otherwise skip to next section Sign Apk File

Create .keystore file

Open Android Studio. Click top menu Build > Generate Signed APK. In the next window click the Create new... button. In the new window, please input in data in all fields. Remember the two Password field i recommend should have the same password; don't use different password; and also remember the save path at top most field Key store path:. After you input all the field click OK button.

Sign Apk File

Now you need to build a signed app with the .keystore file you just created. Follow these steps

  1. Build > Clean Project, wait till it finish cleaning
  2. Build > Generate Signed APK
  3. Click Choose existing... button
  4. Select the .keystore file we just created in the Create .keystore file section
  5. Enter the same password you created while creating in Create .keystore file section. Use same password for Key store password and Key password fields. Also enter the alias
  6. Click Next button
  7. In the next screen; which might be different based on your settings in build.gradle files, you need to select Build Types and Flavors.
  8. For the Build Types choose release from the dropdown
  9. For Flavors however it will depends on your settings in build.gradle file. Choose staging from this field. I used the following settings in the build.gradle, you can use the same as mine, but make sure you change the applicationId to your package name

    productFlavors {
        staging {
            applicationId "com.yourapplication.package"
            manifestPlaceholders = [icon: "@drawable/ic_launcher"]
            buildConfigField "boolean", "CATALYST_DEBUG", "true"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true"
        }
        production {
            buildConfigField "boolean", "CATALYST_DEBUG", "false"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false"
        }
    }
    
  10. Click the bottom two Signature Versions checkboxes and click Finish button.

Almost There:

All the hardwork is done, now the movement of truth. Inorder to access the Staging server backed-up by proxy, you need to make some setting in your real testing Android devices.

Proxy Setting in Android Device:

  1. Click the Setting inside Android phone and then wi-fi
  2. Long press on the connected wifi and select Modify network
  3. Click the Advanced options if you can't see the Proxy Hostname field
  4. In the Proxy Hostname enter the host IP or name you want to connect. A typical staging server will be named as stg.api.mygoodcompany.com
  5. For the port enter the four digit port number for example 9502
  6. Hit the Save button

One Last Stop:

Remember we generated the signed apk file in Sign APK File section. Now is the time to install that APK file.

  1. Open a terminal and changed to the signed apk file folder
  2. Connect your Android device to your machine
  3. Remove any previous installed apk file from the Android device
  4. Run adb install name of the apk file
  5. If for some reason the above command return with adb command not found. Enter the full path as C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe install name of the apk file

I hope the problem might be solved. If not please leave me a comments.

Salam!

小梨窩很甜 2024-12-03 03:53:33

使用 https://www.ssllabs.com/ssltest/ 测试域。

Shihab Uddin 在 Kotlin 中的解决方案。

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException

object {

    val okHttpClient: OkHttpClient
    val gson: Gson
    val retrofit: Retrofit

    init {

        okHttpClient = getOkHttpBuilder()
            // Other parameters like connectTimeout(15, TimeUnit.SECONDS)
            .build()

        gson = GsonBuilder().setLenient().create()

        retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }

    fun getOkHttpBuilder(): OkHttpClient.Builder =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            OkHttpClient().newBuilder()
        } else {
            // Workaround for the error "Caused by: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at".
            getUnsafeOkHttpClient()
        }

    private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
        try {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts: Array<TrustManager> = arrayOf(
                object : X509TrustManager {
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
                }
            )
            // Install the all-trusting trust manager
            val sslContext: SSLContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory,
                trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier { _, _ -> true }
            builder
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
}

如果您使用Glide也会出现同样的错误,图像不会显示。要克服它,请参阅 Glide - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException:未找到证书路径的信任锚如何为 glide 设置 OkHttpClient

@GlideModule
class MyAppGlideModule : AppGlideModule() {

    val okHttpClient = Api.getOkHttpBuilder().build() // Api is the class written above.
    // It is better to create okHttpClient here and not use Api.okHttpClient,
    // because their settings may differ. For instance, it can use its own
    // `addInterceptor` and `addNetworkInterceptor` that can affect on a read JSON.


    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        registry.replace(GlideUrl::class.java, InputStream::class.java,
            OkHttpUrlLoader.Factory(okHttpClient))
    }
}

build.gradle:

// Glide.
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'

更新

我还在 API 16 模拟器上遇到了另一个错误:

例程:SSL23_GET_SERVER_HELLO:tlsv1警报协议版本
(外部/openssl/ssl/s23_clnt.c:741'。

阅读12,我更改了代码:

okHttpClient = getOkHttpBuilder().build()

private fun getOkHttpBuilder(): OkHttpClient.Builder {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        Security.insertProviderAt(Conscrypt.newProvider(), 1)
    }
    return OkHttpClient().newBuilder()
}

// build.gradle:
implementation 'org.conscrypt:conscrypt-android:2.5.1'

我还从 MyApplication 中删除了这些行:

try {
    ProviderInstaller.installIfNeeded(applicationContext)
    val sslContext = SSLContext.getInstance("TLSv1.2")
    sslContext.init(null, null, null)
    sslContext.createSSLEngine()
} catch (e: GooglePlayServicesRepairableException) {
    Timber.e(e.stackTraceToString())
    // Prompt the user to install/update/enable Google Play services.
    GoogleApiAvailability.getInstance().showErrorNotification(this, e.connectionStatusCode)
} catch (e: GooglePlayServicesNotAvailableException) {
    Timber.e(e.stackTraceToString())
    // Prompt the user to install/update/enable Google Play services.
    // GoogleApiAvailability.getInstance().showErrorNotification(this, e.errorCode)
} catch (e: NoSuchAlgorithmException) {
    Timber.e(e.stackTraceToString())
} catch (e: KeyManagementException) {
    Timber.e(e.stackTraceToString())
}

但是 library 添加3.4 Mb 到 apk。

Use https://www.ssllabs.com/ssltest/ to test a domain.

The solution of Shihab Uddin in Kotlin.

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException

object {

    val okHttpClient: OkHttpClient
    val gson: Gson
    val retrofit: Retrofit

    init {

        okHttpClient = getOkHttpBuilder()
            // Other parameters like connectTimeout(15, TimeUnit.SECONDS)
            .build()

        gson = GsonBuilder().setLenient().create()

        retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }

    fun getOkHttpBuilder(): OkHttpClient.Builder =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            OkHttpClient().newBuilder()
        } else {
            // Workaround for the error "Caused by: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at".
            getUnsafeOkHttpClient()
        }

    private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
        try {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts: Array<TrustManager> = arrayOf(
                object : X509TrustManager {
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
                }
            )
            // Install the all-trusting trust manager
            val sslContext: SSLContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory,
                trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier { _, _ -> true }
            builder
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
}

The same error will also appear if you use Glide, images won't show. To overcome it see Glide - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found and How to set OkHttpClient for glide.

@GlideModule
class MyAppGlideModule : AppGlideModule() {

    val okHttpClient = Api.getOkHttpBuilder().build() // Api is the class written above.
    // It is better to create okHttpClient here and not use Api.okHttpClient,
    // because their settings may differ. For instance, it can use its own
    // `addInterceptor` and `addNetworkInterceptor` that can affect on a read JSON.


    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        registry.replace(GlideUrl::class.java, InputStream::class.java,
            OkHttpUrlLoader.Factory(okHttpClient))
    }
}

build.gradle:

// Glide.
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'

UPDATE

I also got another error on API 16 emulator:

routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
(external/openssl/ssl/s23_clnt.c:741'.

Reading 1 and 2, I changed code so:

okHttpClient = getOkHttpBuilder().build()

private fun getOkHttpBuilder(): OkHttpClient.Builder {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        Security.insertProviderAt(Conscrypt.newProvider(), 1)
    }
    return OkHttpClient().newBuilder()
}

// build.gradle:
implementation 'org.conscrypt:conscrypt-android:2.5.1'

I also removed these lines from MyApplication:

try {
    ProviderInstaller.installIfNeeded(applicationContext)
    val sslContext = SSLContext.getInstance("TLSv1.2")
    sslContext.init(null, null, null)
    sslContext.createSSLEngine()
} catch (e: GooglePlayServicesRepairableException) {
    Timber.e(e.stackTraceToString())
    // Prompt the user to install/update/enable Google Play services.
    GoogleApiAvailability.getInstance().showErrorNotification(this, e.connectionStatusCode)
} catch (e: GooglePlayServicesNotAvailableException) {
    Timber.e(e.stackTraceToString())
    // Prompt the user to install/update/enable Google Play services.
    // GoogleApiAvailability.getInstance().showErrorNotification(this, e.errorCode)
} catch (e: NoSuchAlgorithmException) {
    Timber.e(e.stackTraceToString())
} catch (e: KeyManagementException) {
    Timber.e(e.stackTraceToString())
}

But the library adds 3.4 Mb to apk.

-柠檬树下少年和吉他 2024-12-03 03:53:33

我在尝试使用使用自签名证书来公开其测试版本的外部 Web 服务时遇到了同样的问题。以下是我用于全局解决该问题的步骤(它将应用您正在使用的任何框架:Retrofit、oKhttp、HttpUrlConnection)

  1. 在 chrome 中加载域(https://dev.thedomain.private)
  2. 以 .der 格式导出证书(网址附近的挂锁符号,然后是详细信息然后导出并选择der格式)
  3. 将der保存到原始文件夹中 res/raw/dev_thedomain_private.der
  4. 下创建一个安全配置文件>resources/xml
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">dev.thedomain.private</domain>
            <trust-anchors>
                <certificates src="@raw/dev_thedomain_private"/>
            </trust-anchors>
        </domain-config>
    </network-security-config>
  1. 在应用程序标签下引用清单中的安全配置
    <application
        android:networkSecurityConfig="@xml/network_security_config"

你就完成了!该证书现在将被信任...

I had the same problem while trying to consume an external webservice that uses a self signed certificate for exposing its testing version. Here are the steps I've used to solve the issue globally (it will apply whatever the framework you're using : Retrofit, oKhttp, HttpUrlConnection)

  1. Load the domain in chrome (https://dev.thedomain.private)
  2. Export the certificate in .der format (padlock symbol near the url, then details then export and select the der format)
  3. Save the der into the raw forlder res/raw/dev_thedomain_private.der
  4. Create a security config file under resources/xml
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">dev.thedomain.private</domain>
            <trust-anchors>
                <certificates src="@raw/dev_thedomain_private"/>
            </trust-anchors>
        </domain-config>
    </network-security-config>
  1. reference the security config in your manifest under the application tag
    <application
        android:networkSecurityConfig="@xml/network_security_config"

You're done ! The certificate will be trusted now...

赠意 2024-12-03 03:53:33

我遇到了同样的问题,我发现我提供的证书 .crt 文件缺少中间证书。因此,我向服务器管理员询问了所有 .crt 文件,然后以相反的顺序将它们连接起来。

前任。
1.根.crt
2. 交互
3.

我在windows中执行的 myCrt.crt
复制 Inter.crt + Root.crt newCertificate.crt

(这里我忽略了 myCrt.crt)

然后我通过输入流将 newCertificate.crt 文件提供到代码中。
工作完成了。

I had the same problem what i found was that the certificate .crt file i provided missing an intermediate certificate. So I asked all .crt files from my server admin, then concatinated them in reverse order.

Ex.
1. Root.crt
2. Inter.crt
3. myCrt.crt

in windows i executed
copy Inter.crt + Root.crt newCertificate.crt

(Here i ignored myCrt.crt)

Then i provided newCertificate.crt file into code via inputstream.
Work done.

梦毁影碎の 2024-12-03 03:53:33

我知道您不需要信任所有证书,但就我而言,我在一些调试环境中遇到了问题,在这些环境中我们有自签名证书,我需要一个肮脏的解决方案。

我所要做的就是更改 sslContext 的初始化

mySSLContext.init(null, trustAllCerts, null); 

,其中创建 trustAllCerts 如下:

private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return new java.security.cert.X509Certificate[]{};
    }

    public void checkClientTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }
} };

希望这会派上用场。

I know that you don't need to trust all certificates but in my case I had problems with some debugging environments where we had self-signed certificates and I needed a dirty solution.

All I had to do was to change the initialization of the sslContext

mySSLContext.init(null, trustAllCerts, null); 

where trustAllCerts was created like this:

private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return new java.security.cert.X509Certificate[]{};
    }

    public void checkClientTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }
} };

Hope that this will come in handy.

一世旳自豪 2024-12-03 03:53:33

就我而言, root &中间证书已成功安装,但我仍然收到“未找到证书路径的信任锚”。例外!。在挖掘 android 文档后,发现默认情况下,安全连接(使用 TLS 和 HTTPS 等协议的所有应用都信任预装的系统 CA,并且针对 Android 6.0(API 级别 23)及更低版本的应用也默认信任用户添加的 CA 存储。如果您的应用程序在 api 级别高于 23 的操作系统上运行,您应该通过将其地址添加到 network_security_config 来显式允许应用程序信任用户添加的 CA,如下所示:

<domain-config>
        <domain includeSubdomains="true">PUT_YOUR_SERVER_ADDERESS</domain>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
</domain-config>

In my case, the root & intermediate certificates was successfully installed but I still got "Trust anchor for certification path not found." exception!. After digging the android document, found out that by default, secure connections (using protocols like TLS and HTTPS) from all apps trust the pre-installed system CAs, and apps targeting Android 6.0 (API level 23) and lower also trust the user-added CA store by default. If your app running on a OS with api level higher than 23 you should explicitly allow the app to trust user-added CA by adding its address to network_security_config like bellow:

<domain-config>
        <domain includeSubdomains="true">PUT_YOUR_SERVER_ADDERESS</domain>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
</domain-config>
比忠 2024-12-03 03:53:33

我收到的错误消息类似,但原因是自签名证书已过期。
当尝试使用 openssl 客户端时,它给出了当我从 Firefox 检查证书对话框时被忽略的原因。

因此,一般来说,如果证书存在于密钥库中并且其“有效”,则会出现此错误。

The error message I was getting was similar but the reason was that the self signed certificate had expired.
When the openssl client was attempted, it gave me the reason which was overlooked when I was checking the certificate dialog from firefox.

So in general, if the certificate is there in the keystore and its "VALID", this error will go off.

只是在用心讲痛 2024-12-03 03:53:33

我在从 Android 客户端连接到 Kurento 服务器时遇到了同样的问题。
Kurento服务器使用jks证书,所以我必须将pem转换为它。
作为转换的输入,我使用了 cert.pem 文件,它导致了此类错误。
但如果使用 fullchain.pem 而不是 cert.pem - 一切都可以。

I had the same problem while connecting from Android client to Kurento server.
Kurento server use jks certificates, so I had to convert pem to it.
As input for conversion I used cert.pem file and it lead to such errors.
But if use fullchain.pem instead of cert.pem - all is OK.

栀梦 2024-12-03 03:53:33

发生信任锚错误的原因有很多。对我来说,这只是我试图访问 https://example.com/ 而不是 https://www.example.com/

因此,在开始构建您自己的信任管理器之前,您可能需要仔细检查您的 URL(就像我所做的那样)。

The Trust anchor error can happen for a lot of reasons. For me it was simply that I was trying to access https://example.com/ instead of https://www.example.com/.

So you might want to double-check your URLs before starting to build your own Trust Manager (like I did).

眼泪都笑了 2024-12-03 03:53:33

正如其他人已经提到的,该证书不受信任。解决方案是获取该证书并将其作为可信证书包含在您的 http 客户端中。

提取服务器证书,如下所示: 使用 openssl从服务器获取证书

然后为 HttpsURLConnection 客户端创建 SSLSocketFactory,如下所示。

public static void main(String[] args) throws IOException {
    SSLFactory sslFactory = SSLFactory.builder()
            .withDefaultTrustMaterial()     // JDK trusted certificates
            .withSystemTrustMaterial()      // Android system trusted certificates
            .withTrustMaterial("/path/to/truststore.p12", "password".toCharArray()) // your custom list of trusted certificates
            .build();

    HttpsURLConnection connection = (HttpsURLConnection) (new URL("https://api.chucknorris.io/jokes/random")).openConnection();
    connection.setSSLSocketFactory(sslFactory.getSslSocketFactory());
    connection.setHostnameVerifier(sslFactory.getHostnameVerifier());
}

上面的例子是众所周知的 HttpsURLConnection。但是,如果您使用不同的客户端,这可能也很有用,因为它包含近 50 个用于配置 ssl 的不同 http 客户端的列表,请参阅此处:示例 http 客户端 ssl 配置

我需要告诉您,上面的代码片段基于我在此处提供的库:GitHub - SSLContext Kickstart 可以将以下代码片段包含到您的 gradle 构建文件中:

implementation("io.github.hakky54:sslcontext-kickstart:8.1.6")

As others already mentioned the certificate is not trusted. The solution would be to obtain that certificate and include it as a trusted certificate within your http client.

Extract the server certificate as shown here: Using openssl to get the certificate from a server

And then create a SSLSocketFactory for the HttpsURLConnection client as shown below.

public static void main(String[] args) throws IOException {
    SSLFactory sslFactory = SSLFactory.builder()
            .withDefaultTrustMaterial()     // JDK trusted certificates
            .withSystemTrustMaterial()      // Android system trusted certificates
            .withTrustMaterial("/path/to/truststore.p12", "password".toCharArray()) // your custom list of trusted certificates
            .build();

    HttpsURLConnection connection = (HttpsURLConnection) (new URL("https://api.chucknorris.io/jokes/random")).openConnection();
    connection.setSSLSocketFactory(sslFactory.getSslSocketFactory());
    connection.setHostnameVerifier(sslFactory.getHostnameVerifier());
}

The above example is for the well known HttpsURLConnection. However if you are using a different client, this might be also usefull as it contains a list of almost 50 different http clients for configuring ssl, see here: Example http client ssl configuration

I need tell that the above snippet is based on a library which I provide here: GitHub - SSLContext Kickstart which can be included with the following snippet to your gradle build file:

implementation("io.github.hakky54:sslcontext-kickstart:8.1.6")
吃不饱 2024-12-03 03:53:33

在 Gingerbread 手机中,我总是收到此错误:未找到 Android SSL 连接的信任锚,即使我设置为依赖我的证书也是如此。

这是我使用的代码(使用 Scala 语言):

object Security {
    private def createCtxSsl(ctx: Context) = {
        val cer = {
            val is = ctx.getAssets.open("mycertificate.crt")
            try
                CertificateFactory.getInstance("X.509").generateCertificate(is)
            finally
                is.close()
        }
        val key = KeyStore.getInstance(KeyStore.getDefaultType)
        key.load(null, null)
        key.setCertificateEntry("ca", cer)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(key)

        val c = SSLContext.getInstance("TLS")
        c.init(null, tmf.getTrustManagers, null)
        c
    }

    def prepare(url: HttpURLConnection)(implicit ctx: Context) {
        url match {
            case https: HttpsURLConnection ⇒
                val cSsl = ctxSsl match {
                    case None ⇒
                        val res = createCtxSsl(ctx)
                        ctxSsl = Some(res)
                        res
                    case Some(c) ⇒ c
                }
                https.setSSLSocketFactory(cSsl.getSocketFactory)
            case _ ⇒
        }
    }

    def noSecurity(url: HttpURLConnection) {
        url match {
            case https: HttpsURLConnection ⇒
                https.setHostnameVerifier(new HostnameVerifier {
                    override def verify(hostname: String, session: SSLSession) = true
                })
            case _ ⇒
        }
    }
}

这是连接代码:

def connect(securize: HttpURLConnection ⇒ Unit) {
    val conn = url.openConnection().asInstanceOf[HttpURLConnection]
    securize(conn)
    conn.connect();
    ....
}

try {
    connect(Security.prepare)
} catch {
    case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ ⇒
        connect(Security.noSecurity)
}

基本上,我设置为信任我的自定义证书。如果失败,那么我会禁用安全性。这不是最好的选择,但据我所知,对于旧的和有缺陷的手机来说,这是唯一的选择。

这个示例代码可以很容易地翻译成Java。

In Gingerbread phones, I always get this error: Trust Anchor not found for Android SSL Connection, even if I setup to rely on my certificate.

Here is the code I use (in Scala language):

object Security {
    private def createCtxSsl(ctx: Context) = {
        val cer = {
            val is = ctx.getAssets.open("mycertificate.crt")
            try
                CertificateFactory.getInstance("X.509").generateCertificate(is)
            finally
                is.close()
        }
        val key = KeyStore.getInstance(KeyStore.getDefaultType)
        key.load(null, null)
        key.setCertificateEntry("ca", cer)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(key)

        val c = SSLContext.getInstance("TLS")
        c.init(null, tmf.getTrustManagers, null)
        c
    }

    def prepare(url: HttpURLConnection)(implicit ctx: Context) {
        url match {
            case https: HttpsURLConnection ⇒
                val cSsl = ctxSsl match {
                    case None ⇒
                        val res = createCtxSsl(ctx)
                        ctxSsl = Some(res)
                        res
                    case Some(c) ⇒ c
                }
                https.setSSLSocketFactory(cSsl.getSocketFactory)
            case _ ⇒
        }
    }

    def noSecurity(url: HttpURLConnection) {
        url match {
            case https: HttpsURLConnection ⇒
                https.setHostnameVerifier(new HostnameVerifier {
                    override def verify(hostname: String, session: SSLSession) = true
                })
            case _ ⇒
        }
    }
}

and here is the connection code:

def connect(securize: HttpURLConnection ⇒ Unit) {
    val conn = url.openConnection().asInstanceOf[HttpURLConnection]
    securize(conn)
    conn.connect();
    ....
}

try {
    connect(Security.prepare)
} catch {
    case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ ⇒
        connect(Security.noSecurity)
}

Basically, I setup to trust on my custom certificate. If that fails, then I disable security. This is not the best option, but the only choice I know with old and buggy phones.

This sample code, can be easily translated into Java.

寂寞笑我太脆弱 2024-12-03 03:53:33

我也遇到过类似的问题,并且我完全排除了信任所有来源的策略。

我在这里分享我的解决方案应用于在 Kotlin 中实现的应用程序,

我首先建议使用 以下网站获取有关证书及其有效性的信息

如果该证书未在 Android 默认信任存储区中显示为“接受的颁发者” ,我们必须获得该证书并将其合并到应用程序中以创建自定义信任存储

在我的案例中,理想的解决方案是创建一个结合了自定义和 Android 默认信任存储的高级信任管理器

这里他公开了高级 信任存储用于配置他与 Retrofit 一起使用的 OkHttpClient 的代码。

override fun onBuildHttpClient(httpClientBuild: OkHttpClient.Builder) {

        val trustManagerWrapper = createX509TrustManagerWrapper(
            arrayOf(
                getCustomX509TrustManager(),
                getDefaultX509TrustManager()
            )
        )

        printX509TrustManagerAcceptedIssuers(trustManagerWrapper)

        val sslSocketFactory = createSocketFactory(trustManagerWrapper)
        httpClientBuild.sslSocketFactory(sslSocketFactory, trustManagerWrapper)

    }

这样,我就可以使用自签名证书与服务器进行通信,并使用受信任的证书实体颁发的证书与其他服务器进行通信

就是这样,我希望它可以帮助别人。

I have had a similar problem and I have completely ruled out the strategy of trusting all sources.

I share here my solution applied to an application implemented in Kotlin

I would first recommend using the following website to obtain information about the certificate and its validity

If it does not appear as an 'Accepted Issuers' in the Android default trust store, we must get that certificate and incorporate it into the application to create a custom trust store

The ideal solution in my case was to create a high-level Trust Manager that combines the custom and the Android default trust store

Here he exposes the high level code used to configure the OkHttpClient that he used with Retrofit.

override fun onBuildHttpClient(httpClientBuild: OkHttpClient.Builder) {

        val trustManagerWrapper = createX509TrustManagerWrapper(
            arrayOf(
                getCustomX509TrustManager(),
                getDefaultX509TrustManager()
            )
        )

        printX509TrustManagerAcceptedIssuers(trustManagerWrapper)

        val sslSocketFactory = createSocketFactory(trustManagerWrapper)
        httpClientBuild.sslSocketFactory(sslSocketFactory, trustManagerWrapper)

    }

In this way, I could communicate with the server with a self-signed certificate and with other servers with a certificate issued by a trusted certification entity

This is it, I hope it can help someone.

仙女 2024-12-03 03:53:33

我知道这是一篇非常旧的文章,但我在尝试解决我的信任锚问题时看到了这篇文章。我已经发布了我如何修复它。如果您已预安装根 CA,则需要将配置添加到清单中。

https://stackoverflow.com/a/60102517/114265

I know this is a very old article, but I came across this article when trying to solve my trust anchor issues. I have posted how I fixed it. If you have pre-installed your Root CA you need to add a configuration to the manifest.

https://stackoverflow.com/a/60102517/114265

假面具 2024-12-03 03:53:33

有时,当管理员错误地设置证书时会发生这种情况
在这里查看网址
https://www.sslshopper.com/ssl-checker.html

就我而言,出现错误

证书在所有 Web 浏览器中不受信任。您可能需要安装中间/链证书以将其链接到受信任的根证书。了解有关此错误的更多信息。您可以按照适用于您的服务器平台的 GlobalSign 证书安装说明来修复此问题。请注意有关中级证书的部分。

Sometimes it happens when admins setup the certificate incorrectly
Check URL here
https://www.sslshopper.com/ssl-checker.html

In my case, there was an error

The certificate is not trusted in all web browsers. You may need to install an Intermediate/chain certificate to link it to a trusted root certificate. Learn more about this error. You can fix this by following GlobalSign's Certificate Installation Instructions for your server platform. Pay attention to the parts about Intermediate certificates.

怪我入戏太深 2024-12-03 03:53:33

就我而言,网站中的证书是正确的(颁发者 = GlobalSign RSA OV SSL CA 2018),但我下载的证书文件是错误的,因为防病毒软件“拦截”了证书并将新的不同证书传递给从浏览器下载(颁发者 = ESET SSL Filter CA)!!!

检查您的证书文件是否具有正确的颁发者。

In my case, the certificate in the website was correct (Issuer = GlobalSign RSA OV SSL CA 2018), but the certificate file I was downloading was wrong, because of the Antivirus that was "intercepting" the certificate and deliverying a new different certificate to download fron the browsers (Issuer = ESET SSL Filter CA) !!!

Check your certificate file has the correct issuer.

一直在等你来 2024-12-03 03:53:33

就我而言,这是在更新到 Android 8.0 后发生的。 Android 设置为信任的自签名证书使用签名算法 SHA1withRSA。切换到新的证书,使用签名算法 SHA256withRSA 解决了该问题。

In my case this was happening after update to Android 8.0. The self-signed certificate Android was set to trust was using signature algorithm SHA1withRSA. Switching to a new cert, using signature algorithm SHA256withRSA fixed the problem.

不交电费瞎发啥光 2024-12-03 03:53:33

我使用这些方法,其中一种方法在上面的解决方案中对我有用:
第一:

   public  okhttp3.OkHttpClient getUnsafeOkHttpClient() {
    try {
        // Create a trust manager that does not validate 
   certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void 
   checkClientTrusted(java.security.cert.X509Certificate[] chain, 
   String authType) throws CertificateException {
                    }

                    @Override
                    public void 
  checkServerTrusted(java.security.cert.X509Certificate[] chain, 
  String authType) throws CertificateException {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] 
   getAcceptedIssuers() {
                        return new 
  java.security.cert.X509Certificate[]{};
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = 
  SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new 
  java.security.SecureRandom());

        // Create an ssl socket factory with our all-trusting 
       manager
        final SSLSocketFactory sslSocketFactory = 
       sslContext.getSocketFactory();

        okhttp3.OkHttpClient.Builder builder = new 
      okhttp3.OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, 
      (X509TrustManager)trustAllCerts[0]);
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession 
       session) {
                return true;
            }
        });

        okhttp3.OkHttpClient okHttpClient = builder.build();
        return okHttpClient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

第二:

    @SuppressLint("TrulyRandom")
    public static void handleSSLHandshake() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[]{new 
       X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            @Override
            public void checkClientTrusted(X509Certificate[] 
        certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] 
       certs, String authType) {
            }
        }};

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        



  HttpsURLConnection
 .setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new 
    HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception ignored) {
    }
}

和:
将此库放入您的类路径:

 implementation 'com.squareup.okhttp:okhttp:2.3.0'
implementation 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
    androidTestImplementation 'androidx.test.espresso:espresso- 
    core:3.3.0'

确保在您的类中调用它们

I use these methods that one of them is in solutions above works for me :
First:

   public  okhttp3.OkHttpClient getUnsafeOkHttpClient() {
    try {
        // Create a trust manager that does not validate 
   certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void 
   checkClientTrusted(java.security.cert.X509Certificate[] chain, 
   String authType) throws CertificateException {
                    }

                    @Override
                    public void 
  checkServerTrusted(java.security.cert.X509Certificate[] chain, 
  String authType) throws CertificateException {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] 
   getAcceptedIssuers() {
                        return new 
  java.security.cert.X509Certificate[]{};
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = 
  SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new 
  java.security.SecureRandom());

        // Create an ssl socket factory with our all-trusting 
       manager
        final SSLSocketFactory sslSocketFactory = 
       sslContext.getSocketFactory();

        okhttp3.OkHttpClient.Builder builder = new 
      okhttp3.OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, 
      (X509TrustManager)trustAllCerts[0]);
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession 
       session) {
                return true;
            }
        });

        okhttp3.OkHttpClient okHttpClient = builder.build();
        return okHttpClient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Second:

    @SuppressLint("TrulyRandom")
    public static void handleSSLHandshake() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[]{new 
       X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            @Override
            public void checkClientTrusted(X509Certificate[] 
        certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] 
       certs, String authType) {
            }
        }};

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        



  HttpsURLConnection
 .setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new 
    HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception ignored) {
    }
}

and:
put this libraries to your classpath:

 implementation 'com.squareup.okhttp:okhttp:2.3.0'
implementation 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
    androidTestImplementation 'androidx.test.espresso:espresso- 
    core:3.3.0'

be sure that you call them in your class

執念 2024-12-03 03:53:33
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
小红帽 2024-12-03 03:53:33

联系您的客户,如下所示
var httpClient = new HttpClient(new System.Net.Http.HttpClientHandler());

将 https 更改为 http

Relpcae your clicent Like below
var httpClient = new HttpClient(new System.Net.Http.HttpClientHandler());

Change https to http

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文