我想与此网站建立HTTPS连接,尤其是https://elearning.utp.edu.my/
我已经从SSL工具检查过该网站使用的是Entrust_L1K证书,然后我从Chrome浏览器导出证书文件。
我尝试使用Android开发者网站提供的代码。
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = mContext.getResources().openRawResource(R.raw.entrust_l1k);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca = " + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// 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);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setConnectTimeout(7000);
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.connect();
int responseCode = urlConnection.getResponseCode();
switch (responseCode) {
case HttpsURLConnection.HTTP_OK:
InputStream in = urlConnection.getInputStream();
Scanner scanner = new Scanner(in);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next();
} else {
return null;
}
default:
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
但是我仍然收到以下错误代码
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
我尝试过Stack Overflow的多个解决方案。
我希望学习连接到HTTPS而不信任所有证书的最佳做法。 如果有人能指导我,我将不胜感激。
编辑1:显然当我使用Firefox点击“登录”时,它会提示警告显示“elearning.utp.edu.my使用的安全证书无效”。 但是,我可以使用Chrome建立与网站的“安全”连接。 该网站如下:https://elearning.utp.edu.my/login/index.php
答案 0 :(得分:1)
L1K
证书由Root G2
证书签名,因此您也应将其添加到密钥库/信任管理器中:
caInput = mContext.getResources().openRawResource(R.raw.entrust_root_g2);
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca = " + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Use the same keystore.
// Mind the different alias.
keyStore.setCertificateEntry("ca2", ca);
您必须将SSLContext
链接到该连接。您可能希望在实例化连接对象后立即执行此操作:
urlConnection.setSSLSocketFactory(context.getSocketFactory());
注意:虽然您声明要连接到特定网站,但请注意此TLS配置将拒绝任何其他证书。例如。如果您将URL更改为https://stackoverflow.com/
,则TLS握手将失败。如果您想接受自定义证书以及默认证书,请查看此处:https://stackoverflow.com/a/24561444/2657100