1 基本证书原理
常用的基本协议:
客户端执行https请求时,需要由TCP协议建立和释放连接。这就涉及TCP协议的三次握手和四次挥手。
TCP建立连接三次握手
- C-->S: 请求
- C<--S:ACK
- C-->S:确认
TCP的四次挥手
- C-->S: 我的数据发送完成
- C<--S:确认C 发送完成
- C<--S:确认S数据也发送完成
- C-->S:确认结束
http : 明文传输
https : 使用密钥传输数据
对称加密:使用同一key 加密解密, 因此key 传输是由风险的
非对称加密: 使用公钥,私钥,公钥可以任意获取,私钥存在服务器
公钥证书:含有公钥,含有颁发组织,申请者信息....
采用非对称加密对https 缺点的改进,引入了CA, 进行公开秘钥
- 1-服务器的运营人员向数字证书认证机构(CA)提出公开密钥的申请;
- 2- CA通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;
- 3- 如果信息审核通过,CA会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。
证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名;
签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用CA的私钥对信息摘要进行加密,密文即签名; - 4- 客户端在HTTPS握手阶段向服务器发出请求,要求服务器返回证书文件;
- 5- 客户端读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应CA的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即公钥合法;
- 6- 客户端然后验证证书相关的域名信息、有效时间等信息;
- 7- 客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应CA的证书,证书也会被判定非法。
1.1 -HTTPS 单向传输
HTTPS,它还要运行SSL/TLS协议,SSL/TLS协议分两层,第一层是记录协议,主要用于传输数据的加密压缩;第二层是握手协议,它建立在第一层协议之上,主要用于数据传输前的双方身份认证、协商加密算法、交换密钥。
SSL 握手协议的交换流程: (wireshark分析)
功能上分析:
对DH 算法说明,就是采用了随机数+ 算法,使得C与S 可以共享密钥, 在https 是最后C 传给S 的pubkey 是通过公钥证书加密了,因此服务获取后,使用私钥解密即可。在https 首先使用了非对称加密,然后采用了对称加密传输数据。
wireshark: 数据
4357:Client Hello信号,客户端发送随机数字+自己可以支持的加密方法。
4366:Server Hello信号,服务器发送随机数字+选择双方都支持的加密方式,这里选择的是TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,后面还将自己的证书发送了
4369:发送自己的公钥和从CA申请的证书
4375:发送基于DH 的证书,公钥不被证书中包含,需要单独发送,DH 算法相关
4367:server 完成了发送DH, 选择了加密方式,基本完成client 的握手
4386: client 在接受到4366 之后的消息后就可开始了执行相应的client 的逻辑。例如收到4375 发送的证书后,验证证书的有效性【是否具有公钥的第三方数字签名?保证安全尽量公钥还是采用第三方数字签名】,在此之后,这个握手算是结束, client 与server 开始了采用使用对称密钥加解密数据传输。 认为: 这里对称密钥没有通过网络传递,DH 算法传递的只是一些公开的数据,因此保证了对称密钥的安全,不能被网络窃取数据
4405~4407:主要考虑再次通信的方便性,new session ticket,这样的操作是为了之后不用再进行握手,节约服务器的资源
举例再次通信:【没有了发送证书的环节Certificate】
wireshark:分析的原始数据:
链接:https://pan.baidu.com/s/1kdMaIs7tQ7epmUgWqPBgOQ
提取码:2f03
1.2 -HTTPS 双向传输
使用单向验证还是双向验证,是服务器决定的。一般而言,我们的服务器都是对所有客户端开放的,所以服务器默认都是使用单向验证。如果你使用的是Tomcat服务器,在配置文件server.xml中,配置Connector节点的clientAuth属性即可。若为true,则使用双向验证,若为false,则使用单向验证。如果你的服务,只允许特定的客户端访问,那就需要使用双向验证了。
就是相当于两个C[s]<--->S[c], 客户端与服务器端都有各自的公钥与私钥。
总结:
单向验证中,如果是你客户端,你需要拿到服务器的证书,并放到你的信任库中;如果是服务端,你要生成私钥和证书,并将这两个放到你的密钥库中,并且将证书发给所有客户端。
双向验证中,如果你是客户端,你要生成客户端的私钥和证书,将它们放到密钥库中,并将证书发给服务端,同时,在信任库中导入服务端的证书。如果你是服务端,除了在密钥库中保存服务器的私钥和证书,还要在信任库中导入客户端的证书。
再次强调,使用单向验证还是双向验证,是服务器决定的。
2android 实现https 通信
2.1 ,根证书
从It 获取公司的公钥证书与根证书
根证书做成xxx.0 形式放置在
system/ca-certificates/files/
system/ca-certificates/google/files/
#openssl x509 -inform PEM -subject_hash_old -in xxx.pem | head -1
#9849bb9b
#touch 9849bb9b.0
#openssl x509 -inform PEM -subject_hash_old -in xxx.ai.pem -text > 9849bb9b.0
然后看9849bb9b.0, 是否与其他xxx.0格式基本一致就可以了
如果公司的证书是续签的,一般情况根证书是不会变的。
2.2,公钥证书
这个要看code 写法, 从哪里读取公钥证书
InputStream is = getApplicationContext().getAssets().open("srca.cer");
上面的就是公钥srca.cer,如果从IT 哪里获取的不是cer, 就需要抓换
openssl x509 -inform pem -in xxx.pem -outform der -out xxx.cer
查看生成文件的信息:
openssl x509 -inform der -in xxxx.cer -noout -text
其他方式转换REF:
windows 方式转换
2.3 ,服务器证书
服务放置对应的公钥证书与私钥证书就可以了,这个放置的位置通常与开发服务器的code 有关系,有开发code 决定(ex:ota/conf /app.conf)
如何进行调试:
1,服务器已经搭建好,使用ubuntu 系统,测试获取证书,check 是否与服务器公钥一致
openssl s_client -showcerts -connect xxxx(服务器域名):443 </dev/null 2>/dev/null|openssl x509 -outform PEM >mycertfile.pem
openssl s_client -connect {HOSTNAME}:{PORT} -showcerts
2,通过网页获取查看, 查看证书,如果服务有下载连接,可以通过浏览器查看是否可以下载。如果浏览器都是可以的,那就说明,android 设备哪里设定有问题
浏览器查看证书:
其他指令:
openssl x509 -in xxx.crt -out mycert2391236.pem
REF:
Android的证书验证过程
https 基本原理及概念
证书制作
https://mp.weixin.qq.com/s/UiGEzXoCn3F66NRz_T9crA
https://blog.csdn.net/lee244868149/article/details/51790397/