您的位置:首页 > 理论基础 > 计算机网络

正式环境Nginx/Tomcat部署HTTPS(SSL)证书双向认证防抓包/模拟请求

2019-03-04 12:39 1916 查看

双向认证可以提高安全性 单向认证的HTTPS是可以被抓包的 双向认证别人没有你客户端证书和密码的情况下是无法抓包的 服务端检测到证书无效会拒绝连接

首先 取得证书机构颁发的证书文件 这里以腾讯云的免费1年SSL证书为例
这里我们先部署Nginx的 需要Nginx目录里面的两个文件 和根目录的csr文件,先把他复制出来到一个文件夹,文件重命名一下方便敲命令。

首先cmd进入文件夹 输入命令生成服务端的cer文件

openssl x509 -req -days 36500 -sha1 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.cer


至此服务端的证书都不用动了

接下来是生成客户端用的证书用于被服务端信任(需要使用服务端的cer签发客户端的证书才能被信任)

openssl genrsa -out client.key 2048
openssl req -new -out client.csr -key client.key

两个命令生成客户端的主要证书文件 其中生成csr(第二条命令)需要输入各种信息 随便填 不填一直回车也行无所谓 生成完毕的2个客户端证书⤵️

接下来就是重点了
使用服务端的cer key csr请求生成客户端的cer文件(如果需要新的或者更多的客户端证书 一样用服务端的签发客户端的证书就行)

openssl x509 -req -days 36500 -sha1 -extensions v3_req -CA ca.cer -CAkey ca.key -CAserial ca.srl -CAcreateserial -in client.csr -out client.cer

生成两个新文件如下图 注意 ca.srl是刚刚的命令生成的

生成完毕就算完了。

最后使用客户端证书 比如我要在Java程序里使用证书 我要吧客户端的证书合成一个p12格式的证书 生成时输入密码 最好复杂一些 因为是给客户端用的

openssl pkcs12 -export -clcerts -inkey client.key -in client.cer -out client.p12


生成完毕就可以在程序中使用证书去请求服务端了

下面给出Nginx的配置和效果

保存配置重新加载Nginx配置文件然后请求我们的服务器就可以看到我们的请求已经被拒绝了

我们要访问怎么办呢 这里使用OKHTTP来请求我们的服务器看看
状态码400 证书错误

接下来添加我们的客户端证书到请求中(我这里的demo客户端不校验服务器的证书 懒得写 正常要写上的 这种资料网上很多就不讲了)

给出代码

KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
clientKeyStore.load(new FileInputStream(new File("/Users/Smile/ssl/client.p12")), "123456".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, "123456".toCharArray());

SSLContext sslContext = SSLContext.getInstance("TLS");

X509TrustManager x509TrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
};

sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{x509TrustManager}, null);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslContext.getSocketFactory(), x509TrustManager);
Response execute = builder.build()
.newCall(new Request.Builder()
.get()
.url("https://www.dexfun.com")
.build())
.execute();
System.out.println(execute.code());
System.out.println(execute.body().string());

运行代码 已经可以看到下图 状态码200 Welcome to nginx! 请求成功(如果要给Android客户端使用 需要把证书转换成bks格式的证书)

接下来测试抓包

抓包工具已经配置过工具自带的root证书也无法抓到我的双向认证

而单向认证的HTTPS就能抓包成功如下图

接下来是Tomcat配置双向认证
先生成客户端证书

keytool -genkeypair -alias client -keyalg RSA -validity 3650 -keypass 123456 -storepass 123456 -keystore client.jks

然后导出客户端证书

keytool -export -alias client -file client.cer -keystore client.jks -storepass 123456

接下来是从颁发的Tomcat证书导出

keytool -export -alias 你的域名(和证书对应 www.dexfun.com) -file server.cer -keystore server.jks -storepass 证书密码(文件夹里面有个txt文本文档里面有 颁发的)

重点 交换证书

keytool -import -v -alias server -file server.cer -keystore truststore.jks -storepass 123456
#吧客户端的证书导入到服务端(让服务端信任这个客户端的证书 这里和Nginx配置证书不太 如果要多个客户端证书 可能要在导入到server.keystore文件中 我没测试 这里我就不多哔哔了)
keytool -import -v -alias client -file client.cer -keystore server.keystore -storepass 123456

然后修改server.xml文件,配置8443端口

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="${catalina.base}/conf/server.keystore" keystorePass="123456"
truststoreFile="${catalina.base}/conf/server.keystore" truststorePass="123456"/>

keystoreFile:指定服务器密钥库,我放在配置文件同目录 仅供参考。
- keystorePass:密钥库生成时的密码
- truststoreFile:受信任密钥库,和密钥库相同即可
- truststorePass:受信任密钥库密码

将client.jks和truststore.jks分别转换成client.bks和truststore.bks,然后放到android客户端的assert目录下 然后正常使用就行

OK👌 全剧终emmm

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: