SSL handshake with client failed: An unknown issue occurred processing the certificate (certificate_unknown)
private static OkHttpClient getClient() {
OkHttpClient okHttpClient = client;
if (okHttpClient == null) {
try {
Certificate generateCertificate = CertificateFactory.getInstance("X509").generateCertificate(in_cer);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("wallpaper", generateCertificate);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext sSLContext = SSLContext.getInstance("TLS");
sSLContext.init(null, trustManagers, null);
SSLSocketFactory socketFactory = sSLContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(socketFactory, (X509TrustManager) trustManagers[0]);
builder.hostnameVerifier(new HostnameVerifier() { // from class: com.dta.dtawallpaper.util.OkHttpUtil.1
@Override // javax.net.ssl.HostnameVerifier
public boolean verify(String str, SSLSession sSLSession) {
return str.equals("www.dtasecurity.cn");
}
});
......
return builder.build();
} catch (Exception unused) {
return null;
}
}
return okHttpClient;
}
从这里可以看出进行了 客户端证书的校验,和Hostname的校验,就防止了中间人转发的问题,但这也不是问题
function main(){
Java.perform(function (){
//TrustAllManager
var TrustAllManagerClass = Java.registerClass({
name: "TrustAllManager",
implements:[Java.use("javax.net.ssl.X509TrustManager")],
methods: {
checkClientTrusted(chain, authType) {
console.log("checkClientTrusted Called!!")
},
checkServerTrusted(chain, authType) {
console.log("checkServerTrusted Called!!")
},
getAcceptedIssuers() {
return [];
},
}
})
var trustAllManagerHandle = TrustAllManagerClass.$new()
var sslContext = Java.use("javax.net.ssl.SSLContext").getInstance("TLS")
var trustManagers = Java.array("Ljavax.net.ssl.X509TrustManager;",[trustAllManagerHandle])
sslContext.init(null,trustManagers,null)
var sslSocketFactory = sslContext.getSocketFactory()
Java.use("okhttp3.OkHttpClient$Builder").sslSocketFactory.overload('javax.net.ssl.SSLSocketFactory', 'javax.net.ssl.X509TrustManager').implementation = function(arg0, arg1){
console.log("sslSocketFactory Called!!")
return this.sslSocketFactory(sslSocketFactory,trustAllManagerHandle)
}
//HostnameVerify
var MyHostnameVerify = Java.registerClass({
name: "MyHostnameVerify",
implements:[Java.use("javax.net.ssl.HostnameVerifier")],
methods: {
verify(hostname, session){
console.log(hostname)
return true
}
}
})
var myHostnameVerifyHandle = MyHostnameVerify.$new()
Java.use("okhttp3.OkHttpClient$Builder").build.implementation = function(){
this.hostnameVerifier(myHostnameVerifyHandle)
console.log(this.hostnameVerifier)
return this.build()
}
})
}
setImmediate(main)
这里主要是自定义了TrustAllManager类和HostnameVerifier类,来控制其行为实现绕过
ps 这里遇到了一个小问题,但是本应该不存在的 首先我们要在 (SSL Proxy Settings)中设置好host和port ,比如我设置的是*:443 和 *:10081
,但是有一个请求还是没有显示,右键它 选择enable ssl proxying
就好了
参考: https://stackoverflow.com/questions/49117151/charles-proxy-ssl-ssl-proxying-not-enabled-for-this-host