我刚刚解决了这个问题-
Parse SDK for android 在 SelfSigned 证书中不提供开箱即用的支持。
您需要自己修改代码。
第一步 - 相关代码在 ParseHttpClient 中
public static ParseHttpClient createClient(int socketOperationTimeout,
SSLSessionCache sslSessionCache) {
String httpClientLibraryName;
ParseHttpClient httpClient;
if (hasOkHttpOnClasspath()) {
httpClientLibraryName = OKHTTP_NAME;
httpClient = new ParseOkHttpClient(socketOperationTimeout, sslSessionCache);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
httpClientLibraryName = URLCONNECTION_NAME;
httpClient = new ParseURLConnectionHttpClient(socketOperationTimeout, sslSessionCache);
} else {
httpClientLibraryName = APACHE_HTTPCLIENT_NAME;
httpClient = new ParseApacheHttpClient(socketOperationTimeout, sslSessionCache);
}
PLog.i(TAG, "Using " + httpClientLibraryName + " library for networking communication.");
return httpClient; }
如果您的目标支持是更高级的版本,那么 KITKAT -
然后你需要在 ParseURLConnectionHttpClient 构造函数中添加:
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {
if(hostname.equals("YOUR TARGET SERVER")) {
return true;
}
return false;
}});
在其他情况下(旧版本),代码将落入 Apache,我无法使用它 - 所以我做了以下事情:我将 okhttp 库添加到我的应用程序中(使用版本 2.4 - 相同的解析在 build 中表示,最近的包名称不同),然后代码将进入第一个条件,因为它会在路径上找到 okhttp。
您可能应该替换 if 条件顺序,这样它只会在低于 KITKAT 的版本上发生。
在 ParseOkHttpClient 中添加以下自签名证书代码:
public void initCert() {
try {
Log.i("PARSE","initCert");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
String yairCert = "-----BEGIN CERTIFICATE-----\n" +
YOUR CERTIFICATE HERE
"-----END CERTIFICATE-----\n";
InputStream caInput = new ByteArrayInputStream(yairCert.getBytes());
Certificate ca = null;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} catch (CertificateException e) {
e.printStackTrace();
} finally {
try {
caInput.close();
} catch (IOException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
}
}
// 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 context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
Log.i("PARSE","Initiating Self Signed cert");
okHttpClient.setSslSocketFactory(context.getSocketFactory());
try {
cf = CertificateFactory.getInstance("X.509");
} catch (CertificateException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
}
} catch (IOException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (CertificateException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (KeyStoreException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (KeyManagementException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
}
最后一部分是调用这个方法+验证主机名,它也应该发生在构造函数中。
初始化证书();
okHttpClient.setHostnameVerifier(新的 HostnameVerifier() {
@覆盖
公共布尔验证(字符串 s,SSLSession sslSession){
if(s.equals("你的目标服务器")) {
返回真;
}
返回假;
}
});
就是这样。在本地构建 PARSE 并部署到您的应用程序,它会像魅力一样工作。
享受