我对客户端和服务器之间的通信知之甚少,甚至更少关于SSL,但我是一个项目的一部分,我开发了一个在服务器上读取数据的Android应用程序。 我曾经在服务器上打开没有任何安全性的套接字,但我们决定用SSL保护服务器。执行此操作的人向我发送了一个.crt文件,该文件是公钥,信任库文件的格式为.jks。
我被要求在android项目中添加此证书。但我找不到如何做到这一点。这就是为什么如果有人能告诉我如何在Android项目中添加证书以打开SSLSocket,我将非常感激。
谢谢
答案 0 :(得分:1)
对于像您这样的案件,Google有special guide。
以下是您需要的一些引用:
未知的证书颁发机构 在这种情况下,会发生SSLHandshakeException,因为您拥有一个不受系统信任的CA.这可能是因为您拥有来自新CA的证书,该证书尚未受到Android的信任,或者您的应用程序在没有CA的旧版本上运行。通常情况下,CA是未知的,因为它不是公共CA,而是由政府,公司或教育机构等组织发布的私人CA,供其自己使用。
幸运的是,您可以教HttpsURLConnection来信任一组特定的CA.该过程可能有点复杂,因此下面是一个从InputStream获取特定CA的示例,使用它创建KeyStore,然后用于创建和初始化TrustManager。 TrustManager是系统用于验证来自服务器的证书的方法,并且通过从具有一个或多个CA的KeyStore创建一个证书 - 那些将是该TrustManager信任的唯一CA.
给定新的TrustManager,该示例初始化一个新的SSLContext,它提供了一个SSLSocketFactory,可用于覆盖HttpsURLConnection中的默认SSLSocketFactory。这样,连接将使用您的CA进行证书验证。
以下是使用华盛顿大学的组织CA的完整示例:
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
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);
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
所以只需将您的crt文件放到资源文件夹中,然后运行此代码,将caInput
更改为:
InputStream caInput = getResources().openRawResource(R.raw.cert);