openssl详解与应用教程

3 篇文章 1 订阅
2 篇文章 0 订阅

前言

SSL即安全套接字协议(Secure Sockets Layer),是为网络通信提供安全及数据完整性的一种安全协议。SSL在传输层与应用层之间对网络连接进行加密。

使用SSL有很多好处:认证用户和服务器,确保数据发送到正确的客户机和服务器;加密数据以防止数据中途被窃取;维护数据的完整性,确保数据在传输过程中不被改变。
作为一款优秀的产品,SSL功能是必不可少的。

1.概念

数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。

最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。数字证书还有一个重要的特征就是只在特定的时间段内有效。数字证书是一种权威性的电子文档,可以由权威公正的第三方机构,即CA(例如中国各地方的CA公司)中心签发的证书,也可以由企业级CA系统进行签发。

一般证书分有三类,根证书服务器证书客户端证书。根证书,是生成服务器证书和客户端证书的基础,是信任的源头,也可以叫自签发证书,即CA证书。服务器证书,由根证书签发,配置在服务器上的证书。客户端证书,由根证书签发,配置在服务器上,并发送给客户,让客户安装在浏览器里的证书。

在了解SSL的时候可能会遇到很多名词概念,如
对称加密:例如平时给文件加密,加密和解密用的同一密码,即对称加密。

非对称加密:加密时用一个密码,而解锁时需要用另一个密码,即非对称加密。目前很流行的非对称加密算法是RSA算法,它是基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

公钥:公钥是公开的,用来传输对方的随机密钥,只有通过私钥才能解密,这时就只有双方知道密钥了,从而达到安全传输的目的。

私钥:自己保留,只有通过私钥才能解密公钥加密的数据,对于私钥的使用可以设置密码。

2.通信过程

下面以最常见的单向认证为例,简述一下通信过程:

①客户端向服务器发送请求

②服务器将包含公钥的证书通过明文发送给客户端

③客户端通过根证书验证服务器证书是否有效

④如果有效,客户端生成一个随机密钥,也叫对称加密密钥,使用服务器的公钥进行加密传输

⑤服务器通过私钥解密客户端传输的对称加密密钥

⑥这时只有服务器和客户端知道这个对称加密密钥,双方可以进行对称加密传输
在这里插入图片描述

3.通过openssl生成证书

通过openssl version -a查看当前openssl的版本,一般的linux系统会自带SSL。
在这里插入图片描述

通过vim /usr/lib/ssl/openssl.cnf修改配置文件,这里修改了默认文件夹、私钥名、证书名。
在这里插入图片描述
通过cd ssl进入默认文件夹
在这里插入图片描述
在默认文件夹创建所需的目录和文件

mkdir -pv {certs,csr,newcerts,private}
touch {serial,index.txt,index.txt.attr}
-pv可以显示执行进度
在这里插入图片描述

指明证书开始的编号
echo 01 >> serial
在这里插入图片描述

生成根证书私钥
openssl genrsa -out private/ca.key 2048

genrsa --产生rsa密钥命令

-out —输出路径

这里的参数2048,指的是密钥的长度位数,默认长度为512位
在这里插入图片描述

生成自签名证书
openssl req -new -x509 -key private/ca.key -out ca.crt -days 365

-new:表示生成一个新证书签署请求

-x509:专用于CA生成自签证书,如果不是自签证书则不需要此项

-key:用到的私钥文件

-out:证书的保存路径

-days:证书的有效期限,单位是day(天),默认是openssl.cnf的default_days
在这里插入图片描述

生成服务器密钥

openssl genrsa -out private/server.key 2048

在这里插入图片描述

生成请求文件,图中这几项需和根证书一致,后几项不要空着任意填。

openssl req -new -key private/server.key -out csr/server.csr
在这里插入图片描述

颁发证书
openssl ca -in csr/server.csr -out certs/server.crt
在这里插入图片描述

4.通过Python编程验证

下面通过一个例程来模拟单向SSL认证,服务器需要准备好刚刚签发的服务器证书,和一定要好好保管的密钥,客户端只需准备好根证书就行,用来验证服务器的证书。

服务器代码

import socket
import ssl

class server_ssl:
    def build_listen(self):
        # 生成SSL上下文
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        # 加载服务器所用证书和私钥
        context.load_cert_chain('server.crt', 'server.key')

        # 监听端口
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
            sock.bind(('0.0.0.0', 8888))
            sock.listen(5)
            # 将socket打包成SSL socket
            with context.wrap_socket(sock, server_side=True) as ssock:
                while True:
                    # 接收客户端连接
                    client_socket, addr = ssock.accept()
                    # 接收客户端信息
                    msg = client_socket.recv(1024).decode("utf-8")
                    print("receive msg from client {}:{}".format(addr, msg))
                    # 向客户端发送信息
                    msg = "yes , you have client_socketect with server.\r\n".encode("utf-8")
                    client_socket.send(msg)
                    client_socket.close()

if __name__ == "__main__":
    server = server_ssl()
    server.build_listen()

客户端代码

import socket
import ssl

class client_ssl:
    def send_hello(self,):
        # 生成SSL上下文
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        # 加载信任根证书
        context.load_verify_locations('ca.crt')

        # 与服务端建立socket连接
        with socket.create_connection(('0.0.0.0', 8888)) as sock:
            # 将socket打包成SSL socket
            # 一定要注意的是这里的server_hostname不是指服务端IP,而是指服务端证书中的CN。
            with context.wrap_socket(sock, server_hostname='USER1') as ssock:
                # 向服务端发送信息
                msg = "do i connect with server ?".encode("utf-8")
                ssock.send(msg)
                # 接收服务端返回的信息
                msg = ssock.recv(1024).decode("utf-8")
                print("receive msg from server : {}".format(msg))
                ssock.close()

if __name__ == "__main__":
    client = client_ssl()
    client.send_hello()

客户端运行结果
在这里插入图片描述
服务器运行结果
在这里插入图片描述

  • 15
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值