jjzjj

android - OkHttp 信任证书

coder 2023-12-14 原文

在我的 android 应用程序中,我需要使用 OkHttp 库向我的服务器执行一些请求。 我有一个由四个部分组成的 ssl 证书:

  • AddTrustExternalCARoot.crt
  • COMODORSAAddTrustCA.crt
  • COMODORSADomainValidationSecureServerCA.crt
  • www_mydomain_com.crt

我已经在 portecle 1.9 中导入了所有部分,然后我设置了我的 keystore 密码并导出了 .bks 证书。

然后我将这个 mycert.bks 插入到我的应用程序项目的 res/raw 文件夹中。 现在我正在尝试使用以下代码通过 https 连接到我的服务器:

OkHttpClient client = new OkHttpClient();
        try{
            client.setSslSocketFactory(getPinnedCertSslSocketFactory(context));
            RequestBody formBody = new FormEncodingBuilder()
                    .add("params", "xxx")
                    .build();
            Request request = new Request.Builder()
                    .url("https:\\mydomain.com")
                    .post(formBody)
                    .build();

            Response response = client.newCall(request).execute();
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().string();;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }


private SSLSocketFactory getPinnedCertSslSocketFactory(Context context) {
    try {
        KeyStore trusted = KeyStore.getInstance("BKS");
        InputStream in = context.getResources().openRawResource(R.raw.mycert);
        trusted.load(in, "mypass".toCharArray());
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
        TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trusted);
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        Log.e("MyApp", e.getMessage(), e);
    }
    return null;
}

但是我得到一个异常,这是 logcat:

10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: javax.net.ssl.SSLPeerUnverifiedException: Hostname myserver.net not verified:
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err:     certificate: sha1/"mysha1string"
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err:     DN: CN=www.aaa.it,OU=PositiveSSL,OU=Domain Control Validated
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err:     subjectAltNames: [www.aaa.it, aaa.it]
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Connection.connectTls(Connection.java:244)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Connection.connectSocket(Connection.java:199)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Connection.connect(Connection.java:172)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:367)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:328)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:245)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Call.getResponse(Call.java:267)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:224)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:195)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.squareup.okhttp.Call.execute(Call.java:79)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.aaa.android.client.Login$BackgroundTask.doInBackground(Login.java:294)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err:     at com.aaa.android.client.Login$BackgroundTask.doInBackground(Login.java:277)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:288)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err:     at java.lang.Thread.run(Thread.java:818)

问题出在哪里?

更新: 我在这个库上做了很多尝试,我发现了这一点:

  • 如果我自动向 https:\link.com OkHttp 库发出请求 信任所有证书。
  • 如果我只想信任我的证书,我必须执行我认为的解决方案 发表在上面。
  • 如果我不想接受所有主机,但又不使用我的证书,我 可以按照 BNK 的建议使用 hostnameVerifier。

但如果我的解决方案有效,为什么我要发布这个问题?因为我很愚蠢,我向我的 vps url (vpsxxx.net/directory.php) 发出请求,而不是向我的域 (mydomain.it/directory.php) 发出请求。

显然 SSL 证书应用于我的域而不是我的 vps。

我希望这对某人有用。

P.S.:对不起我的英语! :D

最佳答案

假设您的服务器应用程序托管在一台服务器机器中,该机器具有服务器证书,例如,“Issued to”“localhost”。然后,在 verify 方法中,您可以验证 "localhost"

HostnameVerifier hostnameVerifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        HostnameVerifier hv =
            HttpsURLConnection.getDefaultHostnameVerifier();
        return hv.verify("localhost", session);
    }
};

您可以在以下链接中阅读更多内容:

  1. HostnameVerifier

    It is to be used during a handshake if the URL's hostname does not match the peer's identification hostname.

  2. Common Problems with Hostname Verification

    One reason this can happen is due to a server configuration error. The server is configured with a certificate that does not have a subject or subject alternative name fields that match the server you are trying to reach...

然后,您可以通过调用 client.setHostnameVerifier(hostnameVerifier); 在您的应用中使用主机名验证程序。希望这对您有所帮助!

P/S:另一个临时解决方法是 return true; inside verify 方法,但是,不推荐这样做。

关于android - OkHttp 信任证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067368/

有关android - OkHttp 信任证书的更多相关文章

  1. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby - 如何获得带有 SSL 客户端证书的 HTTPS 请求以与 Ruby EventMachine 一起使用? - 2

    我正在尝试使用RubyEventMachine访问使用SSL证书身份验证的HTTPSWeb服务,但我没有让它工作。我编写了以下简单代码块来对其进行端到端测试:require'rubygems'require'em-http'EventMachine.rundourl='https://foobar.com/'ssl_opts={:private_key_file=>'/tmp/private.key',:cert_chain_file=>'/tmp/ca.pem',:verify_peer=>false}http=EventMachine::HttpRequest.new(url).g

  4. ruby - OpenSSL 验证来自自己 CA 的证书 - 2

    大家好,感谢您花时间阅读本文。我需要验证由我自己的CA颁发的证书,我有一个证书。我怎样才能做相当于openssl的openssl验证-CAfile在Ruby代码中?OpenSSL的RDoc在这方面不是很有帮助。我试过:require'openssl'ca=OpenSSL::X509::Certificate.new(File.read('ca-cert.pem'))lic=OpenSSL::X509::Certificate.new(File.read('cert.pem'))putslic.verify(ca)但我得到:test.rb:7:in`verify':wrongargume

  5. Ruby Gem Twitter - 证书验证失败(Twitter::Error::ClientError) - 2

    我正在尝试使用ruby​​gem'twitter',但由于未知原因我无法使用它。这是.rb代码:require'twitter'puts"Greetings,World!"puts"Checkpoint1"Twitter.configuredo|config|config.consumer_key="xxxxxxx"#removedforpostingconfig.consumer_secret="xxxxxxx"#removedforpostingconfig.oauth_token="xxxxxxx"#removedforpostingconfig.oauth_token_secr

  6. ruby - 具有 HTTPS、SSL 客户端证书和 Keep-Alive 支持的 Ruby HTTP 库? - 2

    我正在尝试用Ruby编写一个HTTPS客户端。它将使用HTTPS连接到服务器,传递身份验证token(通过单独的登录过程获得)和SSL客户端证书。我正在使用rest-client执行以下操作:client=RestClient::Resource.new(url,:ssl_client_cert=>OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),:ssl_client_key=>OpenSSL::PKey::RSA.new(File.read('./certificate/client

  7. ruby - 使用自签名证书 - 2

    我只是想了解SSL。我已经在我的本地主机上设置了一个Jetty服务器,并使用Keytool生成了我自己的证书.现在当我去https://localhost:8443/我收到无法信任此证书错误。我用keytool-export-aliaspongus-keystorekeystore-filecertfile.cer创建我认为是客户端需要向服务器进行身份验证的证书。(这是我可能大错特错的地方!)我有以下ruby代码:require'net/https'require'openssl'require'open-uri'puts'yay'ifFile.exists?('certfile.ce

  8. ruby-on-rails - 如何验证服务器SSL证书? - 2

    我是SSL概念的新手,我正在尝试使用HTTParty连接到具有x509相互身份验证的API。我得到了客户端证书、客户端key和服务器证书(都是pem文件)。我让它与客户端证书和key以及verify:false一起工作。下一步是如何验证服务器证书?HTTPParty文档链接https://github.com/jnunemaker/httparty/tree/master/docs#working-with-sslclassServiceClientincludeHTTPartyDEFAULT_HEADERS={'Content-Type'=>'application/json'}.f

  9. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  10. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

随机推荐