Android에서 HttpClient를 사용하여 https://someUrl.com/somePath에 연결합니다. 문제는 사이트의 인증서가 someUrl.com이 아닌 * .someUrl.com에 대한 것이므로 SSLException을 얻습니다. 사이트의 일부분에 절름발이가 있습니다. 그렇지만, 제가 고칠 수 없다면, 저는 붙어 있습니다. HttpClient가 긴장을 풀고 인증서를 수락 할 수있는 방법이 있습니까?Android HttpClient - 인증서의 호스트 이름이 일치하지 않았습니다. <example.com>! = <*. example.com>
답변
이 내 (편집) 솔루션 :
class MyVerifier extends AbstractVerifier {
private final X509HostnameVerifier delegate;
public MyVerifier(final X509HostnameVerifier delegate) {
this.delegate = delegate;
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts)
throws SSLException {
boolean ok = false;
try {
delegate.verify(host, cns, subjectAlts);
} catch (SSLException e) {
for (String cn : cns) {
if (cn.startsWith("*.")) {
try {
delegate.verify(host, new String[] {
cn.substring(2) }, subjectAlts);
ok = true;
} catch (Exception e1) { }
}
}
if(!ok) throw e;
}
}
}
public DefaultHttpClient getTolerantClient() {
DefaultHttpClient client = new DefaultHttpClient();
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) client
.getConnectionManager().getSchemeRegistry().getScheme("https")
.getSocketFactory();
final X509HostnameVerifier delegate = sslSocketFactory.getHostnameVerifier();
if(!(delegate instanceof MyVerifier)) {
sslSocketFactory.setHostnameVerifier(new MyVerifier(delegate));
}
return client;
}
그것은 와일드 카드 도메인이없는 한 기본 동작을 변경하지 않는 장점을 가지고 있으며,이 경우에 2 부분 도메인 (예 : someUrl.com)이 인증서의 일부인 것처럼 재확인합니다. 그렇지 않으면 원래 예외가 다시 전달됩니다. 이는 진정으로 유효하지 않은 인증서가 여전히 실패 함을 의미합니다. 당신이 웹보기를 사용하는 경우
*.someUrl.com
을 원하면 someUrl.com/somePath
대신 www.someUrl.com/somePath
을 줄 수있는 것 같습니다.
아니 무시 호출합니다. www.someUrl.com someUrl.com로 리디렉션 – noah
나는 그것이 쓸모 없다고 생각합니다. https가 정말로 필요합니까? 나는 그렇게 추측 할 것이다. 그러나 그것은 삶을 훨씬 쉽게 만들 것이다. –
사이트가 리디렉션을하지 않을 때 이것은 훌륭한 일시적인 해결책입니다! –
Android의 BouncyCastle이 너무 오래되었으며 와일드 카드 인증서를 인식하지 못합니다.
와일드 카드를 확인하기 위해 고유 한 X509TrustManager를 작성할 수 있습니다.
또는 위험을 수락 할 수있는 경우 인증서 확인을 모두 사용하지 않도록 설정할 수 있습니다. 이 질문을 참조
실제로 ZZ, 사이트 이름 및 인증서 구조에 대한 OP가 올바른 경우 오류 메시지가 정확합니다. ** someUrl.com *은 www.someUrl.com 및 anything.someUrl과 일치해야합니다. co.kr, * someUrl.com 또는 this.that.someUrl.com이 아닙니다. –
단지
webview.clearSslPreferences();
는 SSL 오류
위의 방법을 사용해 보았습니다.하지만 때때로 스택 오버플로 예외가 발생합니다. verify() 메서드는 결코 재귀를 중지하지 않습니다. 수십만 건의 설치 중 일주일에 약 80 회 정도 발생합니다. 이 문제가 생겼습니까? – user291701
@ user291701 문제를 해결하기 위해 코드를 편집했습니다. 나는 그 문제가 당신이 동일한 공장에서 검증자를 다시 설정하게된다고 생각하기 때문에 어떻게 든 자체 위임을 끝낸다. 더 나은 방법을 찾으면 내 대답을 자유롭게 편집 할 수있다. – noah
어쨌든 '미디어 유형이 지원되지 않아 서버가 요청을 처리 할 수 없습니다.'오류가 발생합니다. 이 이유에 대한 단서를 얻지 못했습니다. –