사실, 이번 주, 나는 다음과 같은OkHttp는 : SSLPeerUnverifiedException은 (모토로라 X.509 인증서
과 같은 질문내 휴대 전화에서 OkHttpClient and Certificate Authority Validation in Android
이 서명 한 신뢰할 수있는 인증서를 찾지 못했습니다 Android 4.1.2), 모든 DigiCert CA를 비활성화합니다 (Settings - Security - Trusted credentials - System
). 아래
내 코드 :
public class CertPinActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cert_pin);
try {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("github.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=")
.build();
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(getSSLSocketFactory())
.certificatePinner(certificatePinner)
.build();
Request request = new Request.Builder()
.url("https://github.com/square/okhttp/wiki/HTTPS")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("onFailure","-------------------------------------------------");
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("onResponse", response.body().string());
}
});
} catch (Exception e){
e.printStackTrace();
}
}
private SSLSocketFactory getSSLSocketFactory()
throws CertificateException, KeyStoreException, IOException,
NoSuchAlgorithmException, KeyManagementException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.github); // this is exported from Chrome then stored inside \app\src\main\res\raw path
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
}
내 애플 다음 로그 캣을 얻었다 (죄송합니다 너무 오래 때문에 나는 잘라야)
06-14 09:10:10.065 30176-30211/com.example.okhttps3 E/onFailure: -------------------------------------------------
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: javax.net.ssl.SSLPeerUnverifiedException: Failed to find a trusted cert that signed X.509 Certificate:
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: [
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: [
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: Version: V3
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: Subject: CN=DigiCert SHA2 Extended Validation Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: Signature Algorithm: SHA256WithRSAEncryption, params unparsed, OID = 1.2.840.113549.1.1.11
06-14 09:10:10.065 30176-30211/com.example.okhttps3 W/System.err: Key:
...................................................................................
06-14 09:17:56.813 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.tls.CertificateChainCleaner$BasicCertificateChainCleaner.clean(CertificateChainCleaner.java:132)
06-14 09:17:56.813 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.CertificatePinner.check(CertificatePinner.java:149)
06-14 09:17:56.813 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.io.RealConnection.connectTls(RealConnection.java:252)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.io.RealConnection.establishProtocol(RealConnection.java:196)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:171)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.RealCall.getResponse(RealCall.java:243)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.RealCall.access$100(RealCall.java:30)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-14 09:17:56.823 5934-5984/com.example.okhttps3 W/System.err: at java.lang.Thread.run(Thread.java:856)
그러나, onResponse
는 다음과 같은 경우라고 :
.sslSocketFactory(getSSLSocketFactory())
및.certificatePinner(certificatePinner)
이 모두 제거되었습니다..sslSocketFactory(getSSLSocketFactory())
만 제거되었습니다. (실제로 에뮬레이터에서 시스템 CA가 비활성화 된 경우onFailure
이 호출되고 그 안에 이 던졌습니다..certificatePinner(certificatePinner)
만 제거되었습니다. (너무 오래 내가 잘라 때문에) 아래onResponse
와
로그 캣은 :
06-14 09:06:23.143 26571-26616/com.example.okhttps3 D/onResponse: <!DOCTYPE html>
<html lang="en" class="">
.....
그래서, 내 질문은 :
- 내 질문의 시작 부분에있는 링크와 동일 (실제로 그의 첫 번째 문제);
certificatePinner
을getSSLSocketFactory
과 함께 사용하면 내 앱이javax.net.ssl.SSLPeerUnverifiedException: Failed to find a trusted cert that signed X.509 Certificate
이되는 이유는 무엇입니까? 이SSLPeerUnverifiedException
의 내부 메시지는 this JavaDoc에 언급 된Certificate pinning failure!
과 다릅니다.
UPDATE : 1 문제에 대한
:
이 문제 (시스템/효과적이지 사용자 신뢰할 수있는 자격 증명) 만 안드로이드 4.1를 실행하는 내 휴대폰에서 일어난 것 같은데. 2, 02 장치를 확인 했으므로 제조업체에 문의해야합니다.
"I assume you have to include the full certificate chain (or the root certificate if the server sends you the chain), not only the leave certificate"
아래 @Robert의 코멘트에서, 나는 루트 대신, 다음 스크린 샷과 같이 체인을 완성, 그리고 비록 getSSLSocketFactory
안에 내가 getResources().openRawResource(R.raw.github_rootca);
이제 제 2 호가 해결되었습니다!
첫 번째 "ques ". – Robert
@ 로버트 : [첫 번째 문제는] [이 질문] (http://stackoverflow.com/questions/37772360/okhttpclient-and-certificate-authority-validation-in-android)과 같습니다. 시스템 CA를 비활성화했기 때문에'.sslSocketFactory (getSSLSocketFactory())'가 제거되었지만'onResponse'는 여전히 – BNK