我正在尝试向应用服务器发送HTTP请求,并使用SSL保护。我有一个来自服务器团队的自签名X.509证书。我按照documentation的教程,但仍然获得了SSLHandshakeException
:java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
我正在使用此代码:
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());
有没有人知道如何解决它?
答案 0 :(得分:0)
这就是我设置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
上课:
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
目录中。
我使用slf4android进行日志记录,但您当然可以使用标准Log
类。
希望它会对你有所帮助:)。