Android Studio,javax.net.ssl.SSLHandshakeException:不可接受的证书

pas*_*swd 0 java ssl android android-studio

我正在尝试Android Virtual Device从 Android Studio运行。一切正常,直到我尝试从虚拟设备内部访问任何 Google 服务。我们的网络正在使用公司代理,我们必须安装公司证书才能使应用程序正常工作。我通过 将证书安装到 Java(jdk) keytool -importcert -trustcacerts ...,然后以Android\Android Studio\jre\bin相同的方式安装。然后使用 将证书上传到虚拟机中adb push C:\certs\cert1.cer /sdcard/cert1.cer,并将其应用到 Android 的设置中。但我仍然收到错误

Caused by: javax.net.ssl.SSLHandshakeException: Unacceptable certificate: CN=CompanyName Root CA, OU=IT Department, O='CompanyName Professional' LLC, L=NY, ST=NY, C=EN
Run Code Online (Sandbox Code Playgroud)

无论如何绕过是真的吗?如果我已经导入了证书,为什么它仍然要求提供证书。在浏览器中,如果在虚拟机中打开它,所有网站都可以正常工作。谢谢。

Jor*_*dez 10

对于遇到此错误的任何人,我在 Android Xamarin 应用程序上收到此错误,这是由于设备的日期和时间不同步造成的。


小智 7

最佳解决方案(工作):

创建一个新类:HttpsTrustManager

public class HttpsTrustManager implements X509TrustManager {

    private static TrustManager[] trustManagers;
    private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};

    @Override
    public void checkClientTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {

    }

    @Override
    public void checkServerTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {

    }

    public boolean isClientTrusted(X509Certificate[] chain) {
        return true;
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
        return true;
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return _AcceptedIssuers;
    }

    public static void allowAllSSL() {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }

        });

        SSLContext context = null;
        if (trustManagers == null) {
            trustManagers = new TrustManager[]{new HttpsTrustManager()};
        }

        try {
            context = SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }

        HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }
}
Run Code Online (Sandbox Code Playgroud)

并在HTTP调用之前调用以下函数

HttpsTrustManager.allowAllSSL();
Run Code Online (Sandbox Code Playgroud)


Rob*_*ert 5

将根 CA 证书作为“用户定义的证书”安装到模拟器中是现代 Android 设备(Android 6+)的错误方式。由于谷歌引入了Android 网络安全配置,每个应用程序都必须明确地将用户定义的证书添加到信任列表中:

res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="system"/>
            <certificates src="user"/>
        </trust-anchors>
    </base-config>
</network-security-config>
Run Code Online (Sandbox Code Playgroud)

每个未定义 Android 网络安全配置或具有此类配置但不包含<certificates src="user"/>该条目的应用程序都将忽略您额外安装的证书。

并确保AndroidManifest.xml包含标签中的android:networkSecurityConfig属性<application>

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

此外,一些应用程序(例如 Google 服务和 Play 商店)执行证书/密钥固定,这完全可以防止破坏 HTTPS 流量,除非系统被大量修改:

完全禁用 SSL/TLS 证书检查

您必须根设备并安装 EdXposed/Xposed + 多个模块以允许 SSL/TLS 拦截,例如TrustMeAlreadySSL Unpinning)。

或者,您可以使用Frida和某些脚本来禁用 SSL/TLS 证书检查和一些固定实现。据我所知,基于 Frida 的Objection项目包含一些 SSL 取消固定脚本。

警告:这样做会完全消除设备使用的每个 SSL/TLS/HTTPS 连接的安全性(直到使用的代理)。因此,不仅您,而且每个人都可以拦截设备建立的连接并以这种方式修改它们!