這一片翻譯的很不怎么樣,因?yàn)槲也欢甴ttps協(xié)議,我不是搞服務(wù)器的也不是前端的。
OkHttp嘗試平衡兩個(gè)競(jìng)爭(zhēng)的焦點(diǎn):
- 連接到盡可能多的主機(jī)。其中包括運(yùn)行最新版本的boringssl的高級(jí)主機(jī)和運(yùn)行舊版本的OpenSSL的較少過(guò)時(shí)的主機(jī)。
- 連接的安全性。這包括使用證書(shū)和使用強(qiáng)密碼交換的數(shù)據(jù)的隱私來(lái)驗(yàn)證遠(yuǎn)程Web服務(wù)器。
當(dāng)與HTTPS服務(wù)器的連接時(shí),OkHttp需要知道提供哪些TLS版本和密碼套件。想要最大程度地提高連接性的客戶端,那么他講提供將包括過(guò)時(shí)的TLS版本和弱設(shè)計(jì)密碼套件。要求最大化安全性的嚴(yán)格客戶端將僅限于最新的TLS版本和最強(qiáng)的密碼套件。
- MODERN_TLS是一種連接到現(xiàn)代HTTPS服務(wù)器的安全配置。
- COMPATIBLE_TLS是一種連接到安全但不是當(dāng)前HTTPS服務(wù)器的安全配置。
- CLEARTEXT是用于http://URL 的不安全配置。
默認(rèn)情況下,OkHttp將嘗試一個(gè)MODERN_TLS連接,如果現(xiàn)代配置失敗,則回退到COMPATIBLE_TLS連接。
每個(gè)規(guī)范中的TLS版本和密碼套件可以隨每個(gè)版本而變化。例如,在OkHttp 2.2中,我們放棄了對(duì)SSL 3.0的支持,以響應(yīng)POODLE攻擊。在OkHttp 2.3中,我們放棄了對(duì)RC4的支持。與您的桌面網(wǎng)絡(luò)瀏覽器,保持最新與OkHttp是保持安全的最佳方式。
您可以使用一組自定義的TLS版本和密碼套件來(lái)構(gòu)建您自己的連接規(guī)范。例如,該配置限于三個(gè)高度重視的密碼套件。它的缺點(diǎn)是它需要Android 5.0+和類似的當(dāng)前網(wǎng)絡(luò)服務(wù)器。
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(spec))
.build();
證書(shū)鎖
默認(rèn)情況下,OkHttp只信任主機(jī)平臺(tái)的證書(shū)頒發(fā)機(jī)構(gòu)。此策略最大限度地提高了連接性,但它受到證書(shū)頒發(fā)機(jī)構(gòu)攻擊,例如2011 DigiNotar攻擊。攻擊還會(huì)假定您的HTTPS服務(wù)器的證書(shū)由證書(shū)頒發(fā)機(jī)構(gòu)簽名。
使用CertificatePinner來(lái)限制哪些證書(shū)和證書(shū)頒發(fā)機(jī)構(gòu)受信任。 證書(shū)鎖定提高了安全性,但限制了服務(wù)器團(tuán)隊(duì)更新其TLS證書(shū)的能力。 如果沒(méi)有服務(wù)器的TLS管理員的祝福,請(qǐng)不要使用證書(shū)鎖定!
public CertificatePinning() {
client = new OkHttpClient.Builder()
.certificatePinner(new CertificatePinner.Builder()
.add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
.build())
.build();
}
public void run() throws Exception {
Request request = new Request.Builder()
.url("https://publicobject.com/robots.txt")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
for (Certificate certificate : response.handshake().peerCertificates()) {
System.out.println(CertificatePinner.pin(certificate));
}
}
自定義信任證書(shū)
完整代碼示例顯示如何使用您自己的集來(lái)替換主機(jī)平臺(tái)的證書(shū)頒發(fā)機(jī)構(gòu)。 如上所述,如果沒(méi)有服務(wù)器的TLS管理員的祝福,請(qǐng)不要使用自定義證書(shū)!
private final OkHttpClient client;
public CustomTrust() {
SSLContext sslContext = sslContextForTrustedCertificates(trustedCertificatesInputStream());
client = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory())
.build();
}
public void run() throws Exception {
Request request = new Request.Builder()
.url("https://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
private InputStream trustedCertificatesInputStream() {
... // Full source omitted. See sample.
}
public SSLContext sslContextForTrustedCertificates(InputStream in) {
... // Full source omitted. See sample.
}