1、背景
最近因为公司项目的原因,接触到关于HTTPS方面的东西,新东西有必要记录一下。由于涉及公司的事,不公开。
对于公开的部分,会另外成文。
1.1 参考资料
注:网络上资源很多,关键还是要静下心来。
CA认证原理以及实现(上) https://www.cnblogs.com/mafeng/p/6651917.html
CA认证原理以及实现(下)https://www.cnblogs.com/mafeng/p/6651944.html
理解证书和证书链(三) https://blog.csdn.net/junwua/article/details/80506631
理解证书和证书链 https://blog.csdn.net/junwua/article/details/80506399
网站CA证书获取 https://blog.csdn.net/xintonghanchuang/article/details/103299129
https://blog.csdn.net/liaofeifly/article/details/89230458
SSL双向认证和SSL单向认证的区别 https://www.jianshu.com/p/fb5fe0165ef2
【讲得非常易懂!!一定要看!!】秘钥/证书/https握手/CA相关概念https://blog.csdn.net/m0_37681589/article/details/100038327?utm_source=blogxgwz7
mbed TLS 简明教程(二)https://blog.csdn.net/z2066411585/article/details/79179906
基于mbedTLS实现的嵌入式固件知识产权保护方案 https://www.sohu.com/a/232831658_119709
mbedTLS与AWS双向认证过程函数(里程碑式函数) https://blog.csdn.net/nicholas_duan/article/details/92799308
构建系统(CMake 版) https://docs.espressif.com/projects/esp-idf/zh_CN/v3.3/api-guides/build-system-cmake.html
详解 HTTPS、TLS、SSL、HTTP区别和关系 https://blog.csdn.net/chan70707/article/details/82932153
openssl 生成自签证书及查看证书细节 https://www.cnblogs.com/threegun/p/7130985.html
2、关于HTTPS、TLS、SSL
2.1 HTTPS 、tls/ssl 之间的关系
HTTPS,也称作HTTP over TLS。TLS的前身是SSL,TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。下图描述了在TCP/IP协议栈中TLS(各子协议)和HTTP的关系。
TLS中包括了TLS Record Layer Protocol、TLS HandShake Protocol、TLS Change Spec Protocol 和TLS Alert Protocol。
相对HTTP,HTTPS有数据完整性、数据隐私性、身份验证三个优点。
数据完整性和数据隐私性由TLS Record Protocol保证, 身份认证由TLS Handshaking Protocol实现。
HTTP和HTTPS协议的区别在于
1、HTTPS协议需要到证书颁发机构(Certificate Authority,简称CA)申请证书,收费的。
2、HTTPS是具有安全性的SSL加密传输协议,HTTP是明文传输
3、端口不同HTTPS是443,而HTTP是80端口
4、HTTPS需要身份认证的
2.2 HTTPS是如何进行加密,解密,验证的
步骤1、客户端发起HTTPS请求----------即用户在浏览器中输入一个Https网址,然后连接到server的443端口
步骤2、服务端的配置--------采用HTTPS协议的服务器必须要有一套数字证书。这套证书就是一对公钥和私钥(视为钥匙、锁头的关系))。数字证书可以自己制作,也可以向证书组织申请。区别在于自己颁布的证书需要客户端验证通过,才可以继续访问(如将证书加入浏览器);向受信任的CA公司申请的证书无需验证。
步骤3、传送证书------服务器向客户端传送证书,实际上这个证书就是公钥。
步骤4、客户端解析公钥------由客户端的TLS来完成。首先先验证公钥是否有效();若证书没有问题,那么生成一个随机值,然后用证书(公钥)加密。即随机值被锁头给锁起来了。
步骤5、传送加密信息----传送的是用证书加密后的随机值,目的就是让服务器端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加解密了。
步骤6、服务端用私钥解密信息-----得到客户端传过来的随机值(作为以后传输用的私钥),要传输的信息就用这个随机值进行对称加密。
步骤7、传输加密后的信息----服务端用私钥(随机值)加密后的信息,可以在客户端被还原
步骤8、客户端解密信息
HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL协议中使用了非对称加密,对称加密以及HASH算法。具体如下
1、浏览器将自己支持的一套加密规则发送给网站
2、网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发还给浏览器。证书中包含网址地址,加密公钥以及证书的颁发机构等信息。
3、浏览器获得网站帧数后
3.1 验证证书的合法性
3.2 生成一串随机数的密码,并用证书中提供的公钥加密
3.3 使用约定好的HASH算法计算握手消息,并使用生成的随机数对消息加密,最后将之前生成的所有信息发送给网站。
4、网站接受到浏览器发出的数据后
4.1 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手信息,并验证HASH是否与浏览器发来的一致。
4.2 使用密码加密一段握手信息,发送给浏览器
5、浏览器解密并计算握手信息的HASH,如果与服务器发来的HASH一致,则握手结束。
之后所有的通信将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
在HTTPS安全协议中使用非对称加密算法交换密钥,使用对称加密算法对数据进行加密/解密操作,提高加密/解密效率。
注HASH:
要获得数字证书CA,我们需要使用数字证书管理工具:KeyTool和OpenSSL构建CSR(数字证书签发申请),交由CA机构签发,形成最终的数字证书。
3、关于mbedtls
4、在ESP32 中如何访问指定URL(基于HTTPS)的资源
4.1 单向验证
单向认证 SSL 协议不需要客户拥有CA证书.一般Web应用都是采用SSL单向认证的,原因很简单,用户数目广泛,且无需再通信层对用户身份进行验证。在应用逻辑层保证用户的合法登入。
客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的CA是否可靠,发行者证书的公钥能否正确解开服务器证书的"发行者的数字签名",服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。
4.1.1获取证书
从上面获取到PEM 证书链。
4.2 双向验证
双向认证 SSL 协议要求服务器和用户双方都有证书。应用比较多的在于企业应用对接上,要求客户端做身份验证。
客户端的私钥和证书生成过程:
4.2.1 利用openssl工具生成一个RSA客户端私钥
openssl genrsa -out client.key
注意:生成私钥,需要提供一个至少4位,最多1023位的密码。
4.2.2 生成客户端CSR(证书签名请求)
openssl req -out client.csr -key client.key -new
说明:需要一次输入国家,地区,城市,组织,组织单位, Common Name和Email。其中Common Name,可以写自己的名字或者域名。如果要支持https,Common Name应该与域名保持一致,否则会引起浏览器警告。
可以将CSR发给(提交给)证书颁发机构(CA),CA验证过请求者的身份之后,会出具签名证书,需要花钱。
4.2.3 可以生成x509格式的CA自签名证书
openssl req -new -x509 -keyout ca.key -out ca.crt
4.2.4 用生成的CA证书和私钥为csr文件签名
openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
4.2.4 生成p12格式证书
openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx
4.2.5 生成pem格式证书
有时需要用到pem格式的证书,可以用一下方法合并证书文件(crt)和私钥文件(key)来生成
cat client.crt client.key> client.pem
服务端的亦然。
4.2.1 和4.2.2 两步就是构建密钥对的过程(公钥和私钥)
下图说明了数字证书的签发简单过程。
如果认证机构是我们自己,就可以获得CA自签名证书。就如4.2.3 中生成X509格式的CA自签名证书。
4.3 嵌入到程序中
在ESP32 中单向验证中,要将服务器的证书预先嵌入到程序中,方便在HTTPS配置时指定。ESP32支持pem格式的证书。因此要生成服务器端的pem证书。
有时候在组件中要用到一个二进制文件或者一个文本文件。但是又不希望它重新格式化一个C源文件。此时在ESP-IDF的构建框架内可以选择嵌入二进制数据的方式来嵌入。具体步骤如下链接所示。
https://docs.espressif.com/projects/esp-idf/zh_CN/v3.3/api-guides/build-system.html
在component.mk文件中设置变量COMPONENT_EMBED_FILES,将指定要嵌入的二进制文件嵌入
COMPONENT_EMBED_FILES := server_cert.der
如果文件是文本文件(字符串),则可以使用变量COMPONENT_EMBED_TXTFILES将文本文件的内容当成以null结尾的字符串嵌入。
1 COMPONENT_EMBED_TXTFILES := server_root_cert.pem
文件的内容会被编译荆flash中的.rodata段,并通过符号名称来访问。
1
2 extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end");
符号名称是根据文件的全名生成的,其中的字符/,.,等都会被下划线替代。符号名称中以_binary前缀由objcopy添加。