1.生成服务端/客户端证书

╰─$ openssl genrsa -out server.key 1024
╰─$ openssl req -new -x509 -key server.key -out server.crt -days 3650╰─$ openssl genrsa -out client.key 1024
╰─$ openssl req -new -x509 -key client.key -out client.crt -days 3650将client.key和client.crt合成client.p12。p12文件可以认为是一对公私钥的合体文件,通常会有密码保护;可以通过openssl命令生成(将公私钥两个文件合成得到一个p12文件)
╰─$ openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12╰─$ ls
client.crt client.key client.p12 server.crt server.key

最关键的是域名信息Common Name,这里需要填写服务器的域名地址,比如test.com;也可以填写泛域名,比如*.test.com;如果没有域名,可以直接填写服务端ip地址。

2.启动flask接口

from flask import Flask
app = Flask(__name__)
from flask import request@app.route("/")
def hello():print(dict(request.headers))print('客户端证书: ' + request.headers.get('X-SSL-Client-Cert', '').replace('\n\t', '\n'))print('证书序列号: ' + request.headers.get('X-SSL-serial', ''))print('证书主题: ' + request.headers.get('cert-subject', ''))return "SSLPinning Test"if __name__ == "__main__":app.run(ssl_context=('/Users/wiliam/temp/certificate/server.crt', '/Users/wiliam/temp/certificate/server.key'))

访问https://127.0.0.1:5000

因为用的自签名证书,提示“不安全”是正常的,点击“红色三角形感叹号”可以查看证书

3. mac安装nginx

╰─$ brew install nginx
╰─$ nginx

访问http://localhost:8080/可以看到nginx的欢迎页面

4. 修改nginx配置文件

使用nginx的 -t 参数进行配置检查,即可知道实际调用的配置文件路径及是否调用有效
╰─$ nginx -t
nginx: the configuration file /opt/homebrew/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /opt/homebrew/etc/nginx/nginx.conf test is successful

修改/opt/homebrew/etc/nginx/nginx.conf


#user  nobody;
worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '#                  '$status $body_bytes_sent "$http_referer" '#                  '"$http_user_agent" "$http_x_forwarded_for"';#access_log  logs/access.log  main;sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;#gzip  on;server {listen       8080;server_name  localhost;#charset koi8-r;#access_log  logs/host.access.log  main;location / {root   html;index  index.html index.htm;}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {#    proxy_pass   http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {#    root           html;#    fastcgi_pass   127.0.0.1:9000;#    fastcgi_index  index.php;#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;#    include        fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {#    deny  all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {#    listen       8000;#    listen       somename:8080;#    server_name  somename  alias  another.alias;#    location / {#        root   html;#        index  index.html index.htm;#    }#}# HTTPS server#server {listen       443 ssl;server_name  localhost;ssl_certificate      /Users/wiliam/temp/certificate/server.crt;ssl_certificate_key  /Users/wiliam/temp/certificate/server.key;ssl_client_certificate /Users/wiliam/temp/certificate/client.crt;# ssl_verify_client on/optional/optional_no_ca/off;ssl_verify_client optional_no_ca;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   html;index  index.html index.htm;}location /flask/ {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Real-PORT $remote_port;proxy_set_header X-SSL-Client-Cert $ssl_client_cert;proxy_set_header X-SSL-serial $ssl_client_serial;proxy_set_header cert-subject  $ssl_client_s_dn;proxy_pass https://127.0.0.1:5000/;}}include servers/*;
}

这里开启https服务器,
设置ssl_certificate、ssl_certificate_key、ssl_client_certificate、ssl_verify_client,
添加location /flask/,通过proxy_pass转发请求到flask接口,
通过proxy_set_header把证书信息$ssl_client_cert、$ssl_client_serial、$ssl_client_s_dn设置到请求头里供后端查看


# 重新启动,热启动,修改配置重启不影响线上
╰─$ nginx -s reload;

此时访问https://localhost/flask/可以看到请求转发成功

5.postman导入客户端证书前后对比

用postman请求https://localhost/flask/
没导入客户端证书时请求,flask日志显示无客户端证书

postman导入客户端证书

postman再次请求

6.开启服务端校验客户端证书

nginx配置文件里设置 ssl_verify_client no;

─$ nginx -s reload


此时访问https://localhost/flask/,nginx会提示“No required SSL certificate was sent”

7.将服务端/客户端证书转为bks证书

Android平台只识别bks格式的证书文件
打开http://www.bouncycastle.org/latest_releases.html下载bcprov-jdk18on-172.jar

keytool -importcert -v -trustcacerts -alias 位置1 -file 位置2 -keystore 位置3 -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath 位置4 -storepass 位置5

位置1:证书别名
位置2:cer或crt证书文件的路径
位置3:生成的bks文件的路径
位置4:上面下载的JCE Provider包的位置
位置5:bks的密码,用于确保KeyStore文件本身的安全

命令执行完以后,会在对应目录生成对应的bks文件。

示例

keytool -importcert -v -trustcacerts -alias my_client -file client.crt -keystore client.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk18on-172.jar -storepass 123456keytool -importcert -v -trustcacerts -alias my_server -file server.crt -keystore server.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk18on-172.jar -storepass 123456

8.okhttp绑定client.bks证书

9.验证服务端证书

算出server.crt的sha256

╰─$ openssl x509 -in server.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
Rkw2hU165pITX+5rqOJCPrgDL3Y3TRHLPbygl/wxpsY=
new OkHttpClient.Builder().certificatePinner(new CertificatePinner.Builder().add("172.16.90.153", "sha256/Rkw2hU165pITX+5rqOJCPrgDL3Y3TRHLPbygl/wxpsY=").build())

生成自签名证书

╰─$ openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365                                    130 ↵
Generating a RSA private key
..............................................................................................................................................++++
...............................++++
writing new private key to 'key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GuangDong
Locality Name (eg, city) []:GuangZhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YouMi
Organizational Unit Name (eg, section) []:RD
Common Name (e.g. server FQDN or YOUR name) []:william
Email Address []:╰─$ ls
cert.pem key.pem

Flask开启https

from flask import Flask
app = Flask(__name__)@app.route("/")
def hello():return "SSLPinning Test"if __name__ == "__main__":# app.run(ssl_context='adhoc')  # Flask的临时证书并不是那么好,因为每次服务器运行时,都会通过pyOpenSSL动态生成不同的证书app.run(ssl_context=('/Users/wiliam/temp/cert.pem', '/Users/wiliam/temp/key.pem'))

flask不支持验证客户端证书!
(好像可以???看不懂 https://stackoverflow.com/questions/23262768/two-way-ssl-authentication-for-flask)

mac安装nginx

╰─$ brew install nginx╰─$ where nginx
/opt/homebrew/bin/nginx使用nginx的 -t 参数进行配置检查,即可知道实际调用的配置文件路径及是否调用有效
╰─$ nginx -t
nginx: the configuration file /opt/homebrew/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /opt/homebrew/etc/nginx/nginx.conf test is successful# 重新启动,热启动,修改配置重启不影响线上
nginx -s reload;
# 关闭
nginx -s stop;

访问http://localhost:8080/

nginx的root & index

proxy_set_header X-SSL-CERT $ssl_client_cert;
will save the client certificate (from the incoming request to nginx) into ssl_client_cert variable.
NOTE: You’d have to set the
ssl_verify_client on/optional/optional_no_ca/off;
configuration and it should be anything other than off.
on: will do the full verification on client cert, will require the cert from the client side.
optional: cert isn’t required but if cert is provided, will verify it.
optional_no_ca: cert isn’t required, and won’t be verified.
off: turning the option off. (Not asking for the certs so nothing to save in ssl_client_cert)

查看证书

╰─$ openssl x509 -in client2.crt -noout -text
Certificate:Data:Version: 3 (0x2)Serial Number:58:79:4c:98:66:2e:49:33:be:e2:49:18:72:73:56:65:8a:59:b6:5dSignature Algorithm: sha256WithRSAEncryptionIssuer: C = CN, ST = GuangDong2, L = GuangZhou2, O = YouMi2, OU = RD2, CN = 172.16.90.153ValidityNot Before: Nov 22 05:15:57 2022 GMTNot After : Nov 19 05:15:57 2032 GMTSubject: C = CN, ST = GuangDong2, L = GuangZhou2, O = YouMi2, OU = RD2, CN = 172.16.90.153Subject Public Key Info:Public Key Algorithm: rsaEncryptionRSA Public-Key: (1024 bit)Modulus:00:c4:ee:f1:5e:9b:7d:cc:1b:e3:de:54:d0:b7:10:fd:a6:c3:4a:91:b8:e1:b8:f1:5b:57:ed:5f:5b:a5:0e:7a:ec:2b:0a:be:5f:c4:6e:c5:53:a4:4f:b7:95:f0:56:0c:fa:53:c1:0f:7f:2a:9b:f4:53:37:ce:82:12:84:31:aa:2f:36:5c:1d:98:20:1a:87:9a:07:65:c6:ba:36:77:03:81:4f:10:ca:b8:66:83:37:86:66:2c:d9:35:fe:a4:a8:4d:1b:46:03:97:05:b5:0f:ff:0c:01:c0:1d:b4:fc:63:9a:f8:94:a0:79:0f:1a:9a:07:be:b2:ec:e3:fd:7f:0c:8bExponent: 65537 (0x10001)X509v3 extensions:X509v3 Subject Key Identifier:D2:26:B2:87:B1:25:73:46:F8:8E:96:AD:5A:4C:9F:5A:FC:52:9C:5FX509v3 Authority Key Identifier:keyid:D2:26:B2:87:B1:25:73:46:F8:8E:96:AD:5A:4C:9F:5A:FC:52:9C:5FX509v3 Basic Constraints: criticalCA:TRUESignature Algorithm: sha256WithRSAEncryption6d:d1:af:8a:60:7f:1b:24:38:d2:7d:07:71:6e:68:82:8f:55:60:01:a1:e7:77:a1:9d:e8:52:4a:9f:43:90:64:94:d1:b1:25:04:36:67:31:e1:8a:86:74:d9:30:21:49:2f:0c:b8:3d:55:be:75:99:21:c2:03:18:48:96:ee:36:ca:52:e2:06:e7:52:d6:ed:9b:a4:49:e2:cb:8e:7f:d9:7e:c6:f2:60:ff:90:09:b9:d4:81:28:16:f4:d8:54:01:79:d5:8b:bf:20:29:bd:79:03:ad:83:e8:d7:08:9e:c6:4d:1f:01:49:7c:e7:d3:4f:10:65:9d:3b:d6:53:16:ef

sslpinning实战相关推荐

  1. IDEA的Docker插件实战(Dockerfile篇)

    IDEA的Docker插件实战(Dockerfile篇) IntelliJ IDEA的Docker插件能帮助我们将当前工程制作成Docker镜像.运行在指定的远程机器上,是学习和开发阶段的好帮手,本文 ...

  2. 数据结构(04)— 线性顺序表实战

    1. 设计思路 本实战的实质是完成对学生成绩信息的建立.查找.插入.修改.删除等功能,可以首先定义项目的数据结构,然后将每个功能写成一个函数来完成对数据的操作,最后完成主函数以验证各个函数功能并得出运 ...

  3. 【置顶】利用 NLP 技术做简单数据可视化分析教程(实战)

    置顶 本人决定将过去一段时间在公司以及日常生活中关于自然语言处理的相关技术积累,将在gitbook做一个简单分享,内容应该会很丰富,希望对你有所帮助,欢迎大家支持. 内容介绍如下 你是否曾经在租房时因 ...

  4. 2 用python进行OpenCV实战之图像基本知识

    前言 在这一节,我们将学习图像的基本构成单元--像素,我们将详细的探讨什么是像素?像素是如何使用来构成图像的?然后学习如何通过OpenCV来获取和操纵像素. 1 什么是像素 所有的图像都包含一组像素, ...

  5. PyTorch 高级实战教程:基于 BI-LSTM CRF 实现命名实体识别和中文分词

    20210607 https://blog.csdn.net/u011828281/article/details/81171066 前言:译者实测 PyTorch 代码非常简洁易懂,只需要将中文分词 ...

  6. 实战清除电脑上恶意弹出广告窗口

    实战清除电脑上恶意弹出广告窗口 当你碰到电脑桌面右下角时不时弹出广告,如游戏推广.商品广告等,怎么删也删不掉,这是因为用户不小心安装有捆绑广告推广的软件,系统被静默安装了恶意木马广告,这不仅仅是影响用 ...

  7. deeplearning模型量化实战

    deeplearning模型量化实战 MegEngine 提供从训练到部署完整的量化支持,包括量化感知训练以及训练后量化,凭借"训练推理一体"的特性,MegEngine更能保证量化 ...

  8. DeepLabV3+语义分割实战

    DeepLabV3+语义分割实战 语义分割是计算机视觉的一项重要任务,本文使用Jittor框架实现了DeepLabV3+语义分割模型. DeepLabV3+论文:https://arxiv.org/p ...

  9. 图像合成与风格转换实战

    图像合成与风格转换实战 神经式转移 Neural Style Transfer 如果使用社交分享应用程序或者碰巧是个业余摄影师,对过滤器很熟悉.滤镜可以改变照片的颜色样式,使背景更清晰或人的脸更白.然 ...

  10. Single Shot Multibox Detection (SSD)实战(下)

    Single Shot Multibox Detection (SSD)实战(下) Training 将逐步解释如何训练SSD模型进行目标检测. 2.1. Data Reading and Initi ...

最新文章

  1. [Golang学习笔记] 05 程序实体2 作用域访问权限和变量重声明
  2. 丢掉DDoS的八个幻想
  3. USACO 3.2 kimbits DP
  4. 【数据科学】鱼水说竞赛:如何做好「特征工程」?
  5. 数据库------事务
  6. noip2004普及组第2题 花生采摘
  7. c语言组json包,json格式解析和libjson的用法介绍(关于cjson的使用方法)
  8. [转载] 用pandas或numpy处理数据中的空值(np.isnan()/pd.isnull())
  9. POJ 1573机器人走迷宫
  10. 使用公用计算机的用户如何,如何通过设置权限来管理公用电脑?
  11. Android Fragment之间的跳转
  12. bigemap如何下生成CGCS2000坐标系等高线
  13. 固态硬盘分为哪几种_通俗易懂 SSD固态硬盘接口有哪几种类型的图解
  14. react中使用构建缓存_如何使用React,GraphQL和Okta构建健康跟踪应用
  15. java发送公众号/服务通知模板消息到指定用户(完整流程|亲测可用)
  16. TextSeek使用教程(初级篇) - 文件搜索软件
  17. 解决手机连上电脑热点上不了网的问题
  18. 数据通信系统的基本模型
  19. 约瑟夫环(51nod)
  20. 字符串转码中文乱码问题的进一步理解 UTF-8 GBK转码

热门文章

  1. Jquery获取所有子元素
  2. html仿excel冻结 css,css实例:实现gridview仿excel冻结列
  3. 【精读论文】2015-BMVC-Learning Deep Representations of Appearance and Motion for Anomalous Event Detection
  4. t检验临界值表中的n是什么_t检验临界值分布表
  5. js第1章JavaScript案例:改变网页背景颜色、验证用户输入的密码
  6. 科学健脑,让IQ更上一层楼
  7. 2018研究生毕业论文重复率检测八要点
  8. n−皇后问题 (dfs)
  9. c语言实型变量允许存放整型数,实型变量允许存放整形数吗
  10. R语言入门:使用函数sample进行抽样