Android 无法使用自签名证书实现到服务器的SSL连接
我正在尝试将HTTP请求发送到应用程序服务器,并使用SSL进行保护。我有一份来自服务器团队的自签名X.509证书。我遵循了中的教程,但仍然得到了Android 无法使用自签名证书实现到服务器的SSL连接,android,ssl,https,ssl-certificate,x509certificate,Android,Ssl,Https,Ssl Certificate,X509certificate,我正在尝试将HTTP请求发送到应用程序服务器,并使用SSL进行保护。我有一份来自服务器团队的自签名X.509证书。我遵循了中的教程,但仍然得到了SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚点。 我正在使用以下代码: CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); AssetManager
SSLHandshakeException
:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚点。
我正在使用以下代码:
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
AssetManager assManager = ShoppingHelperApp.getContext().getAssets();
InputStream is = assManager.open("keystore2.crt");
InputStream caInput = new BufferedInputStream(is);
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(context.getSocketFactory());
有人知道如何解决这个问题吗?这就是我如何做类似的事情来设置
OkHttpClient
:
OkHttpClient client = new OkHttpClient();
try {
KeyStore keyStore = SSLUtils.getKeyStore(applicationContext);
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null,trustManagerFactory.getTrustManagers(), new SecureRandom());
client.setSslSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
Log.d("AppName", "cannot create http client", e);
}
SSLUtils
class:
import android.content.Context;
import android.content.res.AssetManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class SSLUtils {
private static final Logger LOG = LoggerFactory.getLogger(SSLUtils.class.getSimpleName());
public static KeyStore getKeyStore(Context context) {
KeyStore keyStore = null;
try {
AssetManager assetManager = context.getAssets();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = assetManager.open("cert.pem");
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
LOG.debug("ca={}", ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
} catch (Exception e) {
LOG.error("Error during getting keystore", e);
}
return keyStore;
}
}
将您的cert.pem
文件放入assets
目录我使用它来记录日志,但您当然可以使用标准的
Log
class
希望它能帮助您:)谢谢您的回复!在我看来,我们的代码片段几乎相同,只是证书的扩展名不同。我试过使用.pem,但也没用:(@mol没什么大不了的;)