1、基本概念
HTTPS:是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包,HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性,HTTPS就是“安全版”的HTTP, HTTPS = HTTP + SSL。
CA证书:如果现在A要与远端的B建立安全的连接进行通信,直接使用对称加密通信,密钥无法安全的送给B;直接使用非对称加密,B使用A的公钥加密,A使用私钥解密,但因为B无法确保拿到的公钥就是A的公钥,因此也不能防止中间人攻击,为了解决上述问题,引入了一个第三方,也就是上面所说的CA(Certificate Authority),CA用自己的私钥签发数字证书,数字证书中包含A的公钥,然后B可以用CA的根证书中的公钥来解密CA签发的证书,从而拿到A的公钥。
2、自签名证书
数字证书除了由第三方私钥签名(比如由ca机构签名),其实也可以用自己的私钥签名,用自己的私钥给自己的公钥签名的证书称为自签名证书,自签名证书可以自我验证,即可以拿证书的公钥解证书的签名,由第三方私钥签名的证书就不是自签名证书,验证时需要由存放第三方公钥的证书验证。
Android对于Https的支持在系统层面上已经帮我们封装的很好了,系统会内置合法ca机构的根证书,只要服务器证书是由这些机构或者是其中间机构签发的那么系统会自动做安全校验,我们不需要做任何事情,直接请求https就可以,但是如果服务器证书是自签名的,就需要我们对请求逻辑做一定的改造,不然你发起的所有请求都会失败,因为系统在做ssl证书校验时会认为这是一个非规请求直接阻断掉。
3、生成自签名证书
我们需要生成一个自签名的证书,可以使用 OpenSSL 工具来生成。
生成一个私钥:openssl genrsa -out mykey.pem 2048
使用私钥生成一个自签名证书:openssl req -new -x509 -key mykey.pem -out mycert.pem -days 365 -subj "/C=US/ST=California/L=San Francisco/O=My Company/CN=example.com"
引用说明:以上代码生成了一个自签名证书,有效期为365天。
4、将证书安装到 Android 设备
将生成的证书安装到 Android 设备中,可以通过设置来完成,将证书文件 mycert.pem 复制到设备上,在设备上打开“设置” -> “安全” -> “安装从存储设备”,找到并安装证书。
5、在应用中加载系统证书
在 Android 应用中,通常使用 HttpsURLConnection 或 OkHttp 来处理 HTTPS 请求,下面是如何加载系统证书的代码示例。
“`java
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.security.KeyStore;
public void setupSSLContext() {
try {
// 创建 KeyStore 实例,并加载系统证书
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keyStoreStream = getResources().openRawResource(R.raw.mycert);
keyStore.load(keyStoreStream, null); // 加载证书,密码为 null
// 创建 TrustManagerFactory 实例
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
// 创建 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
trustManager = trustManagerFactory.getTrustManagers();
sslContext.init(null, trustManager, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
上述代码加载系统证书,并设置 SSL 上下文,以确保 HTTPS 请求使用信任的证书。 6、使用用户证书进行网络请求 要使用用户证书进行网络请求,我们需要设置一个 SSL 上下文,并配置 HttpsURLConnection,以下是使用用户证书的代码示例。 ```java // 使用用户证书进行 HTTPS 请求 public void makeHttpsRequest(String urlString) { try { URL url = new URL(urlString); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); // 设置请求方法 connection.setRequestMethod("GET"); connection.setDoInput(true); // 获取响应 InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); // 输出响应结果 System.out.println("Response: " + response.toString()); } catch (Exception e) { e.printStackTrace(); } }
makeHttpsRequest
方法中,配置了 HTTPS 请求并读取响应内容。
7、验证和调试
在实现完以上步骤后,可以通过日志打印或调试工具,确保系统和用户证书的验证过程没有问题,注意在正式环境中,可结合更严格的安全策略来增强 HTTPS 请求的安全性。
1、问:如何在Android应用中处理自签名证书?
答:在Android应用中处理自签名证书,需要在应用中手动添加对该证书的信任,这通常涉及到创建一个自定义的TrustManager
,并在发起HTTPS请求时使用它,具体步骤包括生成自签名证书、将证书安装到Android设备、在应用中加载系统证书以及使用用户证书进行网络请求。
2、问:为什么需要使用HTTPS而不是HTTP?
答:HTTPS提供了更高的安全性,因为它使用SSL/TLS协议对数据进行加密和身份验证,这样可以防止中间人攻击、窃听和改动数据,确保数据的机密性和完整性,相比之下,HTTP是明文传输的,容易被截获和改动。