我的应用程序通过https连接到我自己的网站(使用有效的Let的加密证书),但Android不信任该证书。它给出了这个例外:
07-21 13:26:56.161 9679-9679/com.abyx.loyalty W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.Connection.connectTls(Connection.java:235)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.Connection.connectSocket(Connection.java:199)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.Connection.connect(Connection.java:172)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:367)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:247)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:405)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:243)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at java.net.URL.openStream(URL.java:1058)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.abyx.loyalty.tasks.LogoTask.downloadLogo(LogoTask.java:140)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.abyx.loyalty.tasks.LogoTask.doInBackground(LogoTask.java:110)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at com.abyx.loyalty.tasks.LogoTask.doInBackground(LogoTask.java:63)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:305)
07-21 13:26:56.162 9679-9679/com.abyx.loyalty W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at java.lang.Thread.run(Thread.java:761)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:549)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:401)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: ... 21 more
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
07-21 13:26:56.163 9679-9679/com.abyx.loyalty W/System.err: ... 31 more
我通过接受我自己的证书(https://developer.android.com/training/articles/security-ssl.html)来关注修复此问题的官方Android指南,但问题仍然存在。
现在,我已经尝试调试此问题并打印出Android从我的网站提取的证书以及我提交给它的证书,但它们是相同的!它怎么还能抱怨而不信任证书呢?
这是我的代码:
public String getJSON(String store, Context context) throws IOException, LogoNotFoundException {
try {
// Load CAs from an InputStream
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.abyx));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
store = URLEncoder.encode(store, "UTF-8");
String response;
URL url = new URL("https://www.abyx.be/loyalty/public/logo/" + URLEncoder.encode(store, "utf-8"));
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.connect();
Certificate[] certificates = connection.getServerCertificates();
for (Certificate cert: certificates) {
System.out.println(cert);
}
connection.setRequestMethod("GET");
int statusCode = connection.getResponseCode();
if (statusCode == 200) {
InputStream in = new BufferedInputStream(connection.getInputStream());
response = IOUtils.toString(in, "UTF-8");
} else if (statusCode == 404) {
throw new LogoNotFoundException();
} else {
throw new IOException("Unable to connect to Loyalty API!");
}
return response;
} catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException | CertificateException e) {
throw new IOException(e);
}
}
这是我正在尝试连接的网站:https://abyx.be
关于我本可以做错的任何想法?
这是我的证书:
-----BEGIN CERTIFICATE-----
MIIF/jCCBOagAwIBAgISA2Mgg80mevuvi+l1QcL/PpYqMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzA3MDgyMzA3MDBaFw0x
NzEwMDYyMzA3MDBaMBIxEDAOBgNVBAMTB2FieXguYmUwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQDDCcTogDVU8bhx3wCMSm3rhgz5mhP2maq3CAh3sbP8
Ug4RBN57irwElxxIAShYbGEXv2bW20b6OAklyTRrKr3lN55v/J8BTTeiHIIQXsaF
TFLPTC7oOUnccsSRgrYRvpLbkWeCjnjAwPJpyi9ELB7Zh0TmG12iolgXOZsKhf0D
7YhEICOYf6hdl/uwS6JK8MzjUADt3Jb2DugHKC+9GZbqW+233gprat+5IaK/YqJ5
lchIbQPneg0BDCwuuBthnAmiQ/yfPzJz5UdXKyXxbEbh1LJVyMSTOqitbg+arzYp
IMMw4l6m+XMKN6Jr0BGRizaR8WvtLW/VKNclba4pgkBuYxDcl6UuT1mSKQjQRTDx
eUKlTG8lft9dcDBIn0KrBbTfDhOk0Fp80FAReeGnnPXQ7QL6uUKhYkFk6skMyoBQ
8aqOoU5KQKMqwXxMu+ZhxUmH45CzTGpvJgHWSGa7+ckFQYXfpo/2iwFuS1UV5sfM
+gbGdnPXWRNXt8qhn3GcVfyhn3BZXi/IBqHAe7Flx2UYF2HP6i+/jgyMl66zpy5Y
1s5OZWgWD4qZL/E/J8Dj1jLHZ3FOnM7YzHs0iFIrm9dd/f6E822NrssqgkZnuhkp
QOUgQVduXXCQv8dsZcitvFjjL9+H6jwNkaE45QRGhDE5v7QPNlvetmqZuVZfRwkx
CwIDAQABo4ICFDCCAhAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
BwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQ8fmT06VJ6tPNf
jLmxnwjXOkBpyTAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggr
BgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRz
ZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRz
ZW5jcnlwdC5vcmcvMB8GA1UdEQQYMBaCB2FieXguYmWCC3d3dy5hYnl4LmJlMIH+
BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggrBgEF
BQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwICMIGe
DIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBieSBS
ZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBD
ZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlwdC5v
cmcvcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBAFMEmzIQEOC7DhQ6XAA8
qm/hHrmUGabQCBQg7METyI17kV4deCLJhv134I2YhRochsBDTOitDH5UwbUJQBAF
ikTQs+NkHX36mWRceFnuytdsKteXhbInf0THEem20LEimjNRtLUo1iTEQcURl6Uo
iiy4LROEjcKYex+Dx01ED9i38/5VU2Dji9e4EbhGhyd+5GQNrL3iXtdHjLT+N0j1
mw3P/2Xp9A8ya8JWYx7s5fBnGq6COfDbKX2NmcuhZOXppqn4rWWukLSzkgsxrwo7
gRqWRGy9pJWVxB8QVNGJ6hxC6hBc3UY2dn7ZH8da3M7by2pjsymDOk7fWjUTR/4f
9S4=
-----END CERTIFICATE-----
这是使用openssl x509
解码的证书。
$ openssl x509 -in temp.pem -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
03:63:20:83:cd:26:7a:fb:af:8b:e9:75:41:c2:ff:3e:96:2a
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3
Validity
Not Before: Jul 8 23:07:00 2017 GMT
Not After : Oct 6 23:07:00 2017 GMT
Subject: CN=abyx.be
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:c3:09:c4:e8:80:35:54:f1:b8:71:df:00:8c:4a:
6d:eb:86:0c:f9:9a:13:f6:99:aa:b7:08:08:77:b1:
b3:fc:52:0e:11:04:de:7b:8a:bc:04:97:1c:48:01:
28:58:6c:61:17:bf:66:d6:db:46:fa:38:09:25:c9:
34:6b:2a:bd:e5:37:9e:6f:fc:9f:01:4d:37:a2:1c:
82:10:5e:c6:85:4c:52:cf:4c:2e:e8:39:49:dc:72:
c4:91:82:b6:11:be:92:db:91:67:82:8e:78:c0:c0:
f2:69:ca:2f:44:2c:1e:d9:87:44:e6:1b:5d:a2:a2:
58:17:39:9b:0a:85:fd:03:ed:88:44:20:23:98:7f:
a8:5d:97:fb:b0:4b:a2:4a:f0:cc:e3:50:00:ed:dc:
96:f6:0e:e8:07:28:2f:bd:19:96:ea:5b:ed:b7:de:
0a:6b:6a:df:b9:21:a2:bf:62:a2:79:95:c8:48:6d:
03:e7:7a:0d:01:0c:2c:2e:b8:1b:61:9c:09:a2:43:
fc:9f:3f:32:73:e5:47:57:2b:25:f1:6c:46:e1:d4:
b2:55:c8:c4:93:3a:a8:ad:6e:0f:9a:af:36:29:20:
c3:30:e2:5e:a6:f9:73:0a:37:a2:6b:d0:11:91:8b:
36:91:f1:6b:ed:2d:6f:d5:28:d7:25:6d:ae:29:82:
40:6e:63:10:dc:97:a5:2e:4f:59:92:29:08:d0:45:
30:f1:79:42:a5:4c:6f:25:7e:df:5d:70:30:48:9f:
42:ab:05:b4:df:0e:13:a4:d0:5a:7c:d0:50:11:79:
e1:a7:9c:f5:d0:ed:02:fa:b9:42:a1:62:41:64:ea:
c9:0c:ca:80:50:f1:aa:8e:a1:4e:4a:40:a3:2a:c1:
7c:4c:bb:e6:61:c5:49:87:e3:90:b3:4c:6a:6f:26:
01:d6:48:66:bb:f9:c9:05:41:85:df:a6:8f:f6:8b:
01:6e:4b:55:15:e6:c7:cc:fa:06:c6:76:73:d7:59:
13:57:b7:ca:a1:9f:71:9c:55:fc:a1:9f:70:59:5e:
2f:c8:06:a1:c0:7b:b1:65:c7:65:18:17:61:cf:ea:
2f:bf:8e:0c:8c:97:ae:b3:a7:2e:58:d6:ce:4e:65:
68:16:0f:8a:99:2f:f1:3f:27:c0:e3:d6:32:c7:67:
71:4e:9c:ce:d8:cc:7b:34:88:52:2b:9b:d7:5d:fd:
fe:84:f3:6d:8d:ae:cb:2a:82:46:67:ba:19:29:40:
e5:20:41:57:6e:5d:70:90:bf:c7:6c:65:c8:ad:bc:
58:e3:2f:df:87:ea:3c:0d:91:a1:38:e5:04:46:84:
31:39:bf:b4:0f:36:5b:de:b6:6a:99:b9:56:5f:47:
09:31:0b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
3C:7E:64:F4:E9:52:7A:B4:F3:5F:8C:B9:B1:9F:08:D7:3A:40:69:C9
X509v3 Authority Key Identifier:
keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1
Authority Information Access:
OCSP - URI:http://ocsp.int-x3.letsencrypt.org
CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
X509v3 Subject Alternative Name:
DNS:abyx.be, DNS:www.abyx.be
X509v3 Certificate Policies:
Policy: 2.23.140.1.2.1
Policy: 1.3.6.1.4.1.44947.1.1.1
CPS: http://cps.letsencrypt.org
User Notice:
Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/repository/
Signature Algorithm: sha256WithRSAEncryption
53:04:9b:32:10:10:e0:bb:0e:14:3a:5c:00:3c:aa:6f:e1:1e:
b9:94:19:a6:d0:08:14:20:ec:c1:13:c8:8d:7b:91:5e:1d:78:
22:c9:86:fd:77:e0:8d:98:85:1a:1c:86:c0:43:4c:e8:ad:0c:
7e:54:c1:b5:09:40:10:05:8a:44:d0:b3:e3:64:1d:7d:fa:99:
64:5c:78:59:ee:ca:d7:6c:2a:d7:97:85:b2:27:7f:44:c7:11:
e9:b6:d0:b1:22:9a:33:51:b4:b5:28:d6:24:c4:41:c5:11:97:
a5:28:8a:2c:b8:2d:13:84:8d:c2:98:7b:1f:83:c7:4d:44:0f:
d8:b7:f3:fe:55:53:60:e3:8b:d7:b8:11:b8:46:87:27:7e:e4:
64:0d:ac:bd:e2:5e:d7:47:8c:b4:fe:37:48:f5:9b:0d:cf:ff:
65:e9:f4:0f:32:6b:c2:56:63:1e:ec:e5:f0:67:1a:ae:82:39:
f0:db:29:7d:8d:99:cb:a1:64:e5:e9:a6:a9:f8:ad:65:ae:90:
b4:b3:92:0b:31:af:0a:3b:81:1a:96:44:6c:bd:a4:95:95:c4:
1f:10:54:d1:89:ea:1c:42:ea:10:5c:dd:46:36:76:7e:d9:1f:
c7:5a:dc:ce:db:cb:6a:63:b3:29:83:3a:4e:df:5a:35:13:47:
fe:1f:f5:2e
答案 0 :(得分:2)
您在Apache服务器配置中遇到错误,SSL Labs表示服务器的证书链不完整。
服务器配置必须包含以下行:
SSLCertificateFile /etc/letsencrypt/live/$DOMAIN/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/$DOMAIN/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/$DOMAIN/chain.pem
第三行很重要。它为检查客户提供完整的证书链。
答案 1 :(得分:0)
最佳选择是修复服务器链配置,如@DeKaNszn所述。之后,不需要额外的客户端代码。
如果您没有访问权限/管理员无法执行此操作,以下代码对我来说效果很好。它要求读取实际的证书并将其提供给TrustManager
。以为我会添加我的解决方案,以防其他人正在寻找这种解决方案。
以下代码创建TrustManager
并将其提供给SocketFactory
。我使用了 okHttp 及其OkHttpClient.Builder
。
为我解决此问题的技巧是将SocketFactory
和TrustManager
都设置为自定义。
与原始问题中的HttpsURLConnection
的用法相比,它看起来非常相似,因此可能只是被遗忘的一行。
private fun updateSslSocketFactory(httpClientBuilder: OkHttpClient.Builder)
{
val trustManagers: Array<out TrustManager> = getKeyStoreTrustManager()
if (trustManagers.size != 1 || trustManagers[0] !is X509TrustManager)
{
throw IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers))
}
val trustManager = trustManagers[0] as X509TrustManager
// Create an SSLContext that uses our TrustManager
val protocol = "TLS"
val socketFactory = getSocketFactory(protocol, trustManagers)
// Update okHttp clientBuilder to use our SocketFactory AND TrustManager
httpClientBuilder.sslSocketFactory(socketFactory, trustManager)
}
private fun getKeyStoreTrustManager(): Array<out TrustManager>
{
val keyStore = ConnectionUtils.instance.readStore() // See next section
// Create a TrustManager that trusts the CAs in our KeyStore
val tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm()
val tmf = TrustManagerFactory.getInstance(tmfAlgorithm)
tmf.init(keyStore)
return tmf.trustManagers
}
private fun getSocketFactory(protocol: String, trustManagers: Array<out TrustManager>?): SSLSocketFactory
{
val context = SSLContext.getInstance(protocol)
context.init(null, trustManagers, null)
return context.socketFactory
}
Kotlin字符串和与读取证书并创建KeyStore
对象有关的函数。为了方便阅读,我将其放在额外的单例ConnectionUtils
中:
private val cert: String = "-----BEGIN CERTIFICATE-----\n [...]" // Your full certificate content here
fun readStore(): KeyStore
{
val cert: Certificate = getCa()
// Create a KeyStore containing our trusted CAs
val keyStoreType = KeyStore.getDefaultType()
val keyStore = KeyStore.getInstance(keyStoreType)
// NOTE: No password for now:
keyStore.load(null, null)
keyStore.setCertificateEntry("ca", cert)
return keyStore
}
private fun getCa(): Certificate
{
// Load CAs from an InputStream
val caInput = cert.byteInputStream(StandardCharsets.UTF_8)
val cf = CertificateFactory.getInstance("X.509")
val cert: Certificate
try
{
cert = cf.generateCertificate(caInput)
Timber.d("Pvlse Cert: %s till %s", (cert as X509Certificate).subjectDN, cert.notAfter)
} finally
{
caInput.close()
}
return cert
}
将证书作为字符串保存在类中可能不是理想的选择,但至少在apk中也不是显而易见的文件,而且处理短文本的速度也更快。因此,我在建立与内部开发人员api的连接(未正确设置证书链修复程序)的连接时决定采用此路线。