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

4ioopgfo  于 2023-05-29  发布在  Android
关注(0)|答案(3)|浏览(710)

我正在尝试从Android Studio运行Android Virtual Device。一切正常,直到我尝试从虚拟设备内部访问任何Google服务。我们的网络使用的是公司代理,我们必须安装公司证书,以便应用程序工作。我通过keytool -importcert -trustcacerts ...将证书安装到Java(jdk),然后以同样的方式将其安装到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

无论如何都是真实的的吗?如果我已经进口了,为什么还要证书呢?在浏览器中,如果在虚拟机中打开它,所有网站都可以正常工作。谢谢

myss37ts

myss37ts1#

对于任何遇到这个错误的人,我在Android Xamarin应用程序上得到了这个错误,它是对设备的日期和时间不同步。

t9eec4r0

t9eec4r02#

将根CA证书作为“用户定义的证书”安装到模拟器中对于现代Android设备(Android 6+)来说是错误的。
默认情况下,用户安装的CA证书不受应用信任。在根设备上,您可以安装新的CA证书作为系统证书,如下所示:

如果您的设备已获得root权限并安装了Magisk,您还可以使用Magisk Move Certificates模块将用户安装的证书移动到系统存储中。
自从Google引入Android Network Security Configuration以来,每个应用都必须显式地将用户定义的证书添加到信任列表中:

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>

未定义Android网络安全配置或具有此类配置但不包含<certificates src="user"/>条目的每个应用都将忽略您额外安装的证书。
并确保AndroidManifest.xml<application>标记中包含android:networkSecurityConfig属性:

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

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

完全禁用SSL/TLS证书检查

您必须root设备并安装LSPosed/Xposed +多个模块以允许SSL/TLS拦截,如TrustMeAlreadySSL Unpinning)。
或者,您可以使用Frida和某些脚本来禁用SSL/TLS证书检查和一些固定实现。据我所知,基于Frida的Objection项目包含一些SSL取消固定脚本。

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

nfs0ujit

nfs0ujit3#

最佳解决方案(工作):

新建一个类: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());
    }
}

并在HTTP调用前调用如下函数

HttpsTrustManager.allowAllSSL();

相关问题