通过openssl学习ssl证书。

通过抓包学习ssl:https://www.cnblogs.com/xiaxveliang/p/13183175.html

通过openssl学习ssl:http://3ms.huawei.com/km/blogs/details/1809919

ssl会话复用:https://cloud.tencent.com/developer/article/1819517

证书格式转换:https://blog.csdn.net/ctwy291314/article/details/80017639

加密解密

加密 → 解密,其实就是将原来的明文文件,使用某种算法,进行计算,得到一段不可读的数据:“密文”,是用来保护数据的,保证数据不被非法窃取。

一.对称加密:速度快,不安全(私钥分发管理困难)

在这里插入图片描述

1.生成私钥和公钥

a.生成RSA秘钥的方法

生成RSA秘钥的方法:

openssl genrsa -des3 -out privkey.pem 2048

注:建议用2048位秘钥,少于此可能会不安全或很快将不安全。

这个命令会生成一个2048位的秘钥,同时有一个des3方法加密的密码,如果你不想要每次都输入密码,可以改成:openssl genrsa -out privkey.pem 2048

b.生成一个证书请求

openssl req -new -key privkey.pem -out cert.csr

这个命令将会生成一个证书请求,当然,用到了前面生成秘钥privkey.pem文件,这里将生成一个新的文件cert.csr,即一个证书请求文件,你可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。

如果是自己做测试,那么证书的申请机构和颁发机构都是自己。就可以用下面这个命令来生成证书:

openssl req -new -x509 -key privkey.pem -out cacert.pem -days 3650

这个命令将用上面生成的秘钥privkey.pem生成一个数字证书cacert.pem

以上步骤或直接使用一个命令即可:openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout privkey.pem -out cacert.pem -days 3650

c.ssl证书在nginx的配置:

server {
    listen       443 ssl;
    server_name  www.a.com;

    charset utf-8;
    #access_log  /var/log/nginx/host.access.log  main;
    
    
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_certificate     /etc/nginx/cacert.pem;
    ssl_certificate_key /etc/nginx/privkey.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on; 
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods *;
    add_header Access-Control-Allow-Headers *;
    add_header Access-Control-Allow-Credentials true;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # location / {
    #     proxy_pass   http://xxx:8081/a;
    #     proxy_redirect off;
    #     proxy_set_header Host $host;
    #     proxy_set_header X-Real-IP $remote_addr;
    #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # }
    
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

这里的ssl_protocols表示什么意思呢?

在nginx中,ssl_protocols表示支持的SSL/TLS协议版本。SSL/TLS是一种加密协议,用于保证客户端和服务器之间的通信安全。ssl_protocols指定了nginx服务器支持的SSL/TLS协议版本,可以设置多个协议版本,以逗号分隔。常见的SSL/TLS协议版本包括:

  • TLSv1.2:TLS版本1.2,是TLSv1.1的升级版,目前被视为最安全的TLS协议版本。

  • TLSv1.3:TLS版本1.3,是TLSv1.2的升级版,提供更快的握手速度和更好的安全性。

在nginx中,可以使用ssl_protocols指定支持的SSL/TLS协议版本,例如:

ssl_protocols TLSv1.2 TLSv1.3;

这表示nginx服务器只支持TLSv1.2和TLSv1.3两个协议版本,如果客户端使用其他版本的协议进行连接,则会被服务器拒绝。通过设置ssl_protocols,可以提高通信的安全性和可靠性。

2.使用私钥加密密码

openssl rsautl -encrypt -inkey privkey.pem -in password.txt -out password.enc

openssl rsautl是OpenSSL中一个用于RSA加密、解密、签名和验证的命令行工具。其中,
rsautl是RSA utility的缩写,用于执行RSA算法相关的操作。
-encrypt选项表示使用RSA算法进行加密操作。
-inkey privkey.pem表示使用指定的私钥文件private.key来加密数据。
-in password.txt表示将要加密的数据来源于文件password.txt,就是明文。
-out password.enc表示加密后的数据将保存到文件password.enc中。

RSA算法是一种非对称加密算法,使用公钥加密,私钥解密。在使用RSA算法进行加密操作时,数据被加密后只能由私钥持有者解密:使用私钥privkey.pem对密码文本password.txt进行加密,生成加密后的文件password.enc。接收者可以使用相应的公钥进行解密。需要注意的是,在实际应用中需要对私钥进行保护,避免私钥泄露或被恶意使用,从而导致数据泄露或被篡改。

3.使用私钥解密密码

openssl rsautl -decrypt -inkey privkey.pem -in password.enc -out password_decrypted.txt

二.非对称加密:速度慢,安全(因为公钥公开,私钥自己保存)

在这里插入图片描述

1.生成私钥和公钥

生成私钥:
openssl genrsa -out suprivate.pem 2048

生成公钥:
openssl rsa -in suprivate.pem -outform PEM -pubout -out supublic.pem

2.使用公钥加密密码

openssl rsautl -encrypt -inkey supublic.pem -pubin -in text.txt -out test.txt.encry

3.使用私钥解密密码

openssl rsautl -decrypt -inkey suprivate.pem -in test.txt.encry -out decrypted.txt

验证私钥、公钥、CA(根证书)之间的有效性

验证CA证书的有效性

openssl verify ca.crt

该命令将验证CA证书是否已被颁发,是否已过期,是否被吊销等。
2. 验证服务器证书和私钥的匹配性

openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5

这两个命令将计算服务器证书和私钥的modulus值,并对其进行哈希。如果两个哈希值相同,则证明服务器证书和私钥是匹配的。
3. 验证服务器证书的有效性

openssl verify server.crt

该命令将验证服务器证书是否已被颁发,是否已过期,是否被吊销等。
4. 验证服务器证书和公钥的匹配性

openssl x509 -noout -pubkey -in server.crt > pubkey.pem
openssl rsa -noout -pubin -in server.key > privkey.pem
openssl pkey -pubin -in pubkey.pem -check -noout
openssl pkey -pubin -in privkey.pem -check -noout

这四个命令将提取服务器证书和私钥中的公钥,并验证它们是否匹配。
如果以上所有命令都没有报错,则说明CA证书、私钥、公钥之间是有效的。

常见报错/疑问

openssl rsautl -encrypt -in plain.txt -inkey cacert.pem -pubin -out plain.txt.encrypt:出现unable to load Public Key

unable to load Public Key错误可能是因为cacert.pem文件中的公钥格式不正确。请确保cacert.pem文件中的公钥格式是正确的PEM格式,并且包含BEGIN PUBLIC KEY和END PUBLIC KEY标识。
如果您不确定cacert.pem文件中的公钥格式是否正确,可以使用以下命令来查看公钥内容:

openssl pkey -in cacert.pem -pubin -text

如果输出结果中包含BEGIN PUBLIC KEY和END PUBLIC KEY标识,并且公钥内容正确,则可以尝试重新运行加密命令:

openssl rsautl -encrypt -in plain.txt -inkey cacert.pem -pubin -out plain.txt.encrypt

如果问题仍然存在,请检查cacert.pem文件路径是否正确,并确保文件具有正确的文件权限。

为啥执行命令:openssl verify ca.crt出现以下报错,但是这个证书可以用的:

error 18 at 0 depth lookup: self signed certificate
error ca.crt: verification failed

答:这个错误提示是因为 ca.crt 是自签名证书,openssl 默认情况下不信任自签名证书,需要手动添加信任。在执行 openssl verify 命令时,openssl 会尝试使用系统中可用的根证书来验证指定的证书,如果找不到合适的根证书,则会报错。使用 -CAfile 或 -CApath 选项指定可信任的证书,这样 openssl 就可以使用这些证书来验证指定的证书。例如:

openssl verify -CAfile ca.crt server.crt

什么是证书链?

证书链(Certificate Chain),也被称为证书路径,是由多个证书组成的一种结构。在 SSL/TLS 协议中,证书链用于验证服务器证书的有效性,以及确认服务器是否可信。
证书链通常由以下几个部分组成:

(1)服务器证书:即服务器的公钥证书,由 CA 颁发,用于证明服务器的身份和公钥信息。

(2)中间证书:如果服务器证书由中间 CA 颁发(实际场景服务证书都是中间CA颁发),则需要包含中间证书。中间证书由下级 CA 颁发,用于证明服务器证书的合法性和信任度。

(3)根证书:根证书是证书链的根节点,也是信任链的最终节点。根证书是由操作系统或浏览器预置的一组受信任的证书,用于验证服务器证书和中间证书的合法性和信任度。
在 SSL/TLS 握手过程中,服务器会将证书链发送给客户端,客户端会根据证书链验证服务器证书的有效性,并确认服务器是否可信。如果证书链中的任何一个证书无效或不可信,则 SSL/TLS 握手将失败,连接将被终止。因此,证书链对于 SSL/TLS 安全连接的建立至关重要。

实际证书申请中,由于权威的CA机构数量不多,若所有的服务器证书都向权威CA机构申请,那么CA机构的工作量就会非常大。因此CA机构采取授权 二级机构的方式来管理证书申请,经授权的二级机构也可以签发服务器证书。这里的CA 机构就是颁发根证书,中间证书则由二级机构颁发
在这里插入图片描述

三.编码算法

为什么要进行base64编码呢?一般是因为二进制进行数据传输时,网络中间的有些路由会把 ascii 码中的不可见字符删除,导致数据不一致,因此一般会进行 url 进行 base64编码。

1.base64 编码

utf-8 -> base64(编码) -> ASCII

两种编码方式:

echo -n 'Hello World!' | base64

cat ca.crt | base64 -w0

cat ca.crt | base64 -w0是将文件ca.crt进行base64编码的命令,具体解释如下:

cat ca.crt:使用cat命令读取ca.crt文件的内容,并将其输出到标准输出中。

|:管道符号,将cat命令的输出作为输入传递给base64命令。

base64:将输入内容进行base64编码。

-w0:指定输出行的最大宽度为0,表示不限制输出行的长度。如果不指定该选项,则默认每行输出76个字符,如果数据量较大则可能会造成显示问题。
因此,cat ca.crt | base64 -w0的含义是将文件ca.crt的内容进行base64编码,并将编码结果输出到标准输出中,每行输出的字符数不限制。

2.base64 解码

ASCII -> base64(解码) -> utf-8

这就为什么url在请求过程中需要进行base64编码了。

echo -n 'SGVsbG8gV29ybGQh' | base64 -d

四.签名验证

私钥签名
openssl dgst -sha1 -sign RSAPrivateKey.pem -out sign.txt.signed sign.txt
公钥验签
openssl dgst -sha1 -verify RSAPublicKey.pem -signature sign.txt.signed sign.txt

发送者使用可以代表自己身份的私钥进行签名。
接受者使用私钥对应的公钥进行验签。这样就实现了对消息发送者身份的验证。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值