前言
该篇博文为工作总结,暂时记录的知识点有 :鄙人对https的拙见, windows 使用openssl 生成没有获取认证的证书(主要适用于平时练习)tomact 及nginx 对https的配合部分转发的配置,以及android请求后台添加ssl认证等小白知识点。本篇文章 大约需要耗时 20分钟。
1.https拙见
HTTPS相当于HTTP的安全版本,在HTTP的基础上添加SSL(Secure Socket Layer),SSL主要负责安全。
SSL 主要作用
1. 认证用户和服务器,确保数据发送到正确的客户机和服务器;(验证证书)
2. 加密数据以防止数据中途被窃取;(加密)
3. 维护数据的完整性,确保数据在传输过程中不被改变。(摘要算法)
HTTPS流程
HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。
- 老大掏钱 我要数字证书(公司没钱,自己想办法。。。)
- 权威机构发放 数字证书 (本地使用openssl 生成证书)
- 服务端部署 数字证书 (本地配置在nginx 中)
- 客户端请求
- 服务端 生成一对非对称加密的密钥对,然后把公钥发给客户端
- 客户端 收到公钥,生成一个随机数,作为上图中那一把密钥,用刚才收到的公钥加密这个密钥
- 客户端 发给 服务器。(儿子接着 我的密钥)
- 服务端 收到加密后的密钥,用本地的第一步自己生成的非对称加密的私钥解密,得到真正的密钥。(我丢你 得到密钥了 来来)
然后 客户端 和服务端 带着这个棒子 不对 ..密钥 在一起搞基. -,-
以上内容为本人的一点拙见 如果有不对还望指出,多谢。(我的刀呢…)
2.openSSL生成数字证书
2.1 安装Openssl
下载地址:http://slproweb.com/products/Win32OpenSSL.html (根据系统选择32位或者64位版本下载安装)。
2.2 配置环境变量
变量名: OPENSSL_HOME 变量值:C:\OpenSSL-Win64\bin; (变量值为openssl安装位置)
在path变量结尾添加如下 : %OPENSSL_HOME%;
2.3 创建私钥
首先我们先在nginx 安装目录下 创建一个 ssl文件夹用于存放 数字证书相关文件,在当前文件夹右键打开命令行。
在命令行中执行命令: openssl genrsa -des3 -out ds.key 1024 (ds文件名可以自定义),如下图所示:
之后你就发现文件夹中已经出现了 后缀名为 .key 的文件
2.4 创建csr证书
在命令行中执行命令: openssl req -new -key ds.key -out ds.csr (key文件为刚才生成的文件,ds为自定义文件名)
其中key文件为刚才生成的文件。
执行上述命令后,需要输入一系列的信息。输入的信息中最重要的为Common Name,比如我输入的是localhost。其它的内容随便填。
2.5 去除密码
在加载SSL支持的Nginx并使用上述私钥时除去必须的口令,否则会在启动nginx的时候需要输入密码。
复制ds.key并重命名为ds.copy.key。
在命令行中执行如下命令以去除口令:openssl rsa -in ds.copy.key -out ds.key
2.6 生成crt证书
openssl x509 -req -days 365 -in ds.csr -signkey ds.key -out ds.crt
经过上边几个步骤,我们可以得到4个文件,我们主要使用到将会是key 和 crt文件。
到这里 openSSL 生成我们需要的数字证书已经说完,
3. tomact nginx 配置https
网上搜索到的很多文章在描述 Nginx + Tomcat 启用 HTTPS 支持的时候,都必须在 Nginx 和 Tomcat 两边同时配置 SSL 支持。但是我提供 配置的方案是浏览器和 Nginx 之间走的 HTTPS 通讯,而 Nginx 到 Tomcat 通过 proxy_pass 走的是普通 HTTP 连接。
3.1 nginx 配置修改
我的这个文件在C:\nginx\conf目录下。用任意一个编辑器(如Sublime Text之类)打开这个nginx.conf文件
server {
# http 默认端口为80 , https 默认端口为443
listen 443 ssl;
server_name localhost;
#这里地址是我服务器地址,你们按照自己文件路径填写注意//符号
ssl_certificate C://dsPulse//ssl//test.crt;
ssl_certificate_key C://dsPulse//ssl//test.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_connect_timeout 240;
proxy_send_timeout 240;
proxy_read_timeout 240;
# 我这里 转的地址是我的 tomact地址
proxy_pass http://127.0.0.1:8080;
}
}
其中最为关键的就是 ssl_certificate 和 ssl_certificate_key 这两项配置,其他的按正常配置。不过多了一个 proxy_set_header X-Forwarded-Proto https; 配置
3.2 tomact修改
找到 tomact 安装路径,找到配置文件 server 文件
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"
proxyPort="443"/>
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
` <Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
remoteIpProxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto"
/>
</Host>
</Engine>
</Engine>
</Service>
但是特别特别注意的是必须有proxyPort=”443″,这是整篇文章的关键,当然 redirectPort 也必须是 443。同时 节点的配置也非常重要
修改完 tomact 后启动tomact ,启动 nginx 。建议使用 nginx 命令
常用的 nginx 命令
start nginx # 启动Nginx
nginx.exe -s stop # 快速停止Nginx,可能并不保存相关信息
nginx.exe -s quit # 完整有序的停止Nginx,并保存相关信息
nginx.exe -s reload # 重新载入Nginx,当配置信息修改,需要重新载入这些配置时使用此命令。
nginx.exe -s reopen # 重新打开日志文件
nginx -v # 查看Nginx版本
至于启动成功或者失败,则要看下 nginx/ log /log 文件查看是否有报错,如果成功 log包下会有一个 nginx.pid 文件。当然 也可以使用 postman 模拟访问测试 配置是否成功。
4 android 端代码修改
首先我这边 android 使用的 网络插件为 okhttp 当然如果您使用的是 retofit 道理是一样的 。
android 端需要key 文件来作为公钥,我们将服务器的 文件 下载到本地,将crt 文件转变为 cer文件,并且使用 编辑文件打开获取到 加密串,当然如果你不想将数据拿出来,也可以直接 在 android 工程下新建 raw 文件夹,详细操作 请查看 弘扬博客:弘扬 https
下图便是我项目中 okhttp util 部分代码
private OkHttpClient.Builder builder;
private OkHttpClient client;
private static MyOkHttp instance;
private static final String SSL_KEY = "自己的key字符串";
public MyOkHttp() {
builder = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS)
.connectTimeout(8, TimeUnit.SECONDS)
.writeTimeout(8, TimeUnit.SECONDS);
SSLSocketFactory sslSocketFactory = getSSLSocketFactory(new Buffer().writeUtf8(SSL_KEY).inputStream());
if (sslSocketFactory != null) {
builder.sslSocketFactory(sslSocketFactory);
};
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
// 强行设置证书 安全(其实是降低安全性了)
return true;
}
});
client = builder.build();
}
/**
* ssl 工厂类
* @param certificates certificates
* @return SSLSocketFactory
*/
private static SSLSocketFactory getSSLSocketFactory(InputStream... certificates) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
try {
if (certificate != null){
certificate.close();
}
} catch (IOException e) {
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init
(
null,
trustManagerFactory.getTrustManagers(),
new SecureRandom()
);
return sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
主要添加的东西就在 SSLSocketFactory sslSocketFactory = getSSLSocketFactory(new Buffer().writeUtf8(SSL_KEY).inputStream());这一行,buffer 为 okio中的,通过工厂类 获取到 SSLSocketFactory 。然后builder.sslSocketFactory(sslSocketFactory); 当然 这些设置完基本就可以了,但是由于 我的 ssl是自己生成的,所以如果 有跟我的情况是一样的 就需要添加 HostnameVerifier ,强制将证书 设置为 安全的,如果你的 ssl 是 权威机构发布的 则不用这样麻烦。
另外 由于项目 使用的混编,所以通过 webview 加载 https界面的时候出现了白屏的问题,这里也提一下 解决方案(截止 2018年7月26日 17:41:15):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 允许其加载混合网络协议内容 (http https)
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webview.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// 接收证书 (openssl 自己生成证书)
handler.proceed();
}
}
上边代码 已经注释的很清楚 了,饿死了 加会班 溜了 ,该篇文章 比较初级,只用于记录自己的开发经历 和 知识点分享,如果您发现 鄙人 那里写的不对,麻烦指正 ,我会积极听取的 当然 我会带着我的刀 (:зゝ∠) 。。。
来源:CSDN
作者:Yang19950329
链接:https://blog.csdn.net/qq_27948659/article/details/81223455