美文网首页
PRO-007:理解SSL过程与机制

PRO-007:理解SSL过程与机制

作者: 杨强AT南京 | 来源:发表于2019-01-28 10:59 被阅读28次

本主题主要是通过一个例子说明SSL的过程与机制。

一、理解SSL的加密过程与机制

  SSL加密机制实际是一种信任机制,这个在现实有很多例子:比如印章就是一种信任机制。尽快常用加密技术不完全类似印章的原理,但本质都差不多。
  SSL中数据通信都采用加密,其加密的机制使用的是CA签名加密机制。

1. 对称加密与非对称加密

  加密算法分为两种:对称加密和非对称加密。
     |- 对称加密就是发送双发使用相同的密钥对消息进行加解密,常见的对称加密为DES、3DES,AES等。
    |- 非对称加密是发送双方各自拥有一对公钥私钥,其中公钥是公开的,私钥是保密的。当发送方向接收方发送消息时,发送方利用接收方的公钥对消息进行加密,接收方收到消息后,利用自己的私钥解密就能得到消息的明文。其中非对称加密方法有RSA、Elgamal、ECC等。

  CA加密机制就是一种非对称加密机制。

2. 数字签名

  数字签名在网络通讯中的过程如下:
    |- 当通信A端向B端发送信息时,会将报文生成报文摘要,同时对报文摘要进行hash计算,得到hash值,然后对hash值进行加密,然后将加密的hash值放置在报文后面,这个加密后的hash值就称为签名。
     |- 通信A端将报文、签名和数字证书一同发送给B端。B端收到这些信息后,会首先验证签名,利用签名算法对签名进行解密,得到报文摘要的hash值,然后将得到的报文生成报文摘要并利用签名hash算法生成新的hash值,通过对比这两个hash值是否一致,就能判断信息是否完整,是否是由真正的通信A端发送的。

  数字签名有两个作用:
     |- 确认消息发送方可靠
     |- 确认消息完整准确。

3. SSL加密过程

  1. 使用openssl工具生成CA证书
    产生一个证书文件与私钥。

  2. 使用openssl工具生成需要签名的服务器(或者客户端)证书与私钥。
    产生一个待签名证书与私钥。

  3. 使用openssl工具,用CA证书对服务器证书签名。
    产生一个签名证书

二、 使用openssl工具产生CA签名证书实现

1. 产生CA根证书与私钥

openssl req -newkey rsa:2048 -passout pass:123456 -keyout ca_rsa_private.pem -x509 -days 365 -out ca.crt -subj "/C=CN/ST=SC/L=CD/O=MAGE/OU=TEACHING/CN=NO/emailAddress=1234567@qq.com"

  使用的是RSA非对称加密,两个重要参数说明:
   -keyout ca_rsa_private.pem :指定生成的密钥文件;
   -out ca.crt:指定生成证书的文件。

在终端执行输出:

localhost:certs yangqiang$ openssl req -newkey rsa:2048 -passout pass:123456 -keyout ca_rsa_private.pem -x509 -days 365 -out ca.crt -subj "/C=CN/ST=SC/L=CD/O=MEGE/OU=TEACHING/CN=NO/emailAddress=1234567@qq.com"
Generating a 2048 bit RSA private key
....................+++
...............+++
writing new private key to 'ca_rsa_private.pem'
-----
创建的根证书与私钥的结果

2. 产生服务器(或者客户端)待签名证书与私钥

openssl req -newkey rsa:2048 -passout pass:server -keyout server_rsa_private.pem  -out server.csr -subj "/C=CN/ST=BJ/L=CP/O=MAGEZongbu/OU=MNGT/CN=SERVER/emailAddress=38395870@qq.com"

  其中两个关注的参数说明:
    |- -out server.csr 指定生成的待签名证书。
    |- -keyout server_rsa_private.pem 指定生成的服务器(或者客户端)私钥。
    |- -passout pass:server 密码(这个在服务器加载整数与私钥的时候,需要每次都输入,如果不想输入,可以生成没有密码的私钥。)

localhost:certs yangqiang$ openssl req -newkey rsa:2048 -passout pass:server -keyout server_rsa_private.pem  -out server.csr -subj "/C=CN/ST=BJ/L=CP/O=MAGEZongbu/OU=MNGT/CN=SERVER/emailAddress=38395870@qq.com"
Generating a 2048 bit RSA private key
......................................................................+++
................................+++
writing new private key to 'server_rsa_private.pem'
-----
服务器证书与私钥结果

3. 对服务器证书进行签名

openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca_rsa_private.pem -passin pass:123456 -CAcreateserial -out server.crt

   重要参数说明:
     |- -in server.csr 需要签名的整数。
     |- -CA ca.crt 根证书
     |- -CAkey ca_rsa_private.pem 根证书私钥
     |- -out server.crt 生成的签名证书(可以使用的)

localhost:certs yangqiang$ openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca_rsa_private.pem -passin pass:123456 -CAcreateserial -out server.crt
Signature ok
subject=/C=CN/ST=BJ/L=CP/O=MAGEZongbu/OU=MNGT/CN=SERVER/emailAddress=38395870@qq.com
Getting CA Private Key
最后生成签名的服务器证书结果

三、使用python实现SSL服务器认证加密

  也可以实现客户认证加密,也可以实现双向认证加密。

1. ssl模块的API结构

  使用help与dir可以仔细阅ssl模块的帮助与API结构,实际上核心的类就两个:
     |- SSLContext
       |- SSLSocket
  在help中可以看到其继承结构如下:
    |- socket.socket(_socket.socket)
      |- SSLSocket
        |- 包含socket中方法,也包含SSL特色的网络通信操作函数。
     |- _ssl._SSLContext(builtins.object)
      |- SSLContext
        |- init(self, protocol=<_SSLMethod.PROTOCOL_TLS: 2>) :指定版本
        |- load_cert_chain(self, /, certfile, keyfile=None, password=None) :加载证书与私钥
        |- wrap_socket(self, sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname=None, session=None):对socket通信进行签名加密处理。

import ssl
# print(dir(ssl))
# print(dir(ssl.SSLContext))
# help(ssl.SSLContext)
# help(ssl.SSLSocket)
# print(dir(ssl.SSLSocket))

2. SSL socket服务器端实现

# coding = utf-8
import ssl
import socket

# 1. 创建SSL上下文,需要指定版本,缺省的是PROTOCOL_TLS,我们指定服务器签名PROTOCOL_TLS_SERVER
# 这一步的关键是选择合适的版本,每个不同的版本之间是不互融的。
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)

# 2. 加载证书与服务器私钥
ctx.load_cert_chain(certfile='./certs/server.crt',     # 服务器已经签名的证书
                    keyfile='./certs/server_rsa_private.pem',   # 服务器私钥
                    password='server')         # 生成服务器时输入的密码(这里不指定,就需要输入)

# 3. 创建socket
server_socket = socket.socket(
    socket.AF_INET,
    socket.SOCK_STREAM,
    socket.IPPROTO_TCP)

# 4. 使用ctx创建一个包装器socket,该socket具有签名加密功能。
ssl_server_socket = ctx.wrap_socket(
    sock=server_socket,             # 被包装的socket
    server_side=True)               # 指定是服务器测签名加密

# 5. 正常的socket通信操作
# 绑定服务器地址
ssl_server_socket.bind(('', 8443))     # 443时SSL通用端口,注意使用元组表示地址格式
# 监听
ssl_server_socket.listen(2)
while True:
    # 接受客户连接
    print('等待客户连接!')
    client_socket, client_address = ssl_server_socket.accept()
    print('有客户连接:', client_address)
    # 接受客户数据
    info = client_socket.recv(1024).decode("utf-8")
    print(f"从客户{client_address}接受的信息{info}")
    # 给客户发送一个信息
    client_socket.send('来自服务器的信息!收到没有?'.encode('utf-8'))
    client_socket.close()
    break

ssl_server_socket.close()

下面是输出次效果:

等待客户连接!
有客户连接: ('127.0.0.1', 52427)
从客户('127.0.0.1', 52427)接受的信息来自客户的数据!

3. SSL socket客户端实现

# coding = utf-8
import ssl
import socket

# 1.创建SSL通信上下文
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)

# 2.加载根证书
ctx.load_verify_locations('./certs/ca.crt')

# 3.创建一个客户端socket
client_socket = socket.socket(
    socket.AF_INET,
    socket.SOCK_STREAM,
    socket.IPPROTO_TCP)

# 4.创建socket包装器,实现SSL通信
ssl_client_socket = ctx.wrap_socket(
    sock=client_socket,
    server_side=False,
    server_hostname='SERVER')  # 这个值是识别创建服务器证书的产品名,就是CN指定的名字


# 5.通用的socket通信模式
# 连接到服务器
ssl_client_socket.connect(('127.0.0.1',8443))
# 发送数据
ssl_client_socket.send('来自客户的数据!'.encode('utf-8'))
# 接受数据
info = ssl_client_socket.recv(1024).decode("utf-8")
print(f"从服务器接受的信息:{info}")
ssl_client_socket.close()

下面是输出效果:

从服务器接受的信息:来自服务器的信息!收到没有?

  这里只是通过证书说明SSL中的签名加密过程,在这个基础上,可以实现客户端签名认证与双向签名认证。

  注意:上面两个程序不能同时在ipython中执行,因为ipython是单线程,服务器运行起来,客户端没有办法执行。

备注:
本文使用的三个指令:

openssl req -newkey rsa:2048 -passout pass:123456 -keyout ca_rsa_private.pem -x509 -days 365 -out ca.crt -subj "/C=CN/ST=SC/L=CD/O=MEGE/OU=TEACHING/CN=NO/emailAddress=1234567@qq.com"

openssl req -newkey rsa:2048 -passout pass:server -keyout server_rsa_private.pem  -out server.csr -subj "/C=CN/ST=BJ/L=CP/O=MAGEZongbu/OU=MNGT/CN=SERVER/emailAddress=38395870@qq.com"

openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca_rsa_private.pem -passin pass:123456 -CAcreateserial -out server.crt

相关文章

  • PRO-007:理解SSL过程与机制

    本主题主要是通过一个例子说明SSL的过程与机制。 一、理解SSL的加密过程与机制   SSL加密机制实际是一种信任...

  • Nginx配置Https单向、双向认证

    SSL相关概念及原料请参考OpenSSL 与 SSL 数字证书概念贴、SSL/TLS原理详解 为了便于理解,我们...

  • SSL(安全套阶层)/TLS(传输层安全)

    SSL/TLS协议运行机制的概述图解SSL/TLS协议HTTPS背后的加密算法TLS协议分析 与 现代加密通信协议...

  • SSL/TLS握手协议

    根据理解整理的握手协议原理图如下: 参考文章:SSL/TLS协议详解SSL / TLS 工作原理和详细握手过程SS...

  • 重拾网络基础

    Https的加密机制 https运行于SSL之上,SSL运行在TCP之上,是添加了认证和加密机制的HTTP。端口为...

  • Java基础 (20) 类加载

    1)类加载机制谈谈对ClassLoader(类加载器)的理解2)JVM加载时机与加载过程3)对象创建过程 一. C...

  • 数据安全及加密

    一、简述 SSL 加密的过程用了哪些加密方法,为何这么作? SSL 加密的过程,此处不再赘述。SSL 加密,在过程...

  • Rails配置项force_ssl与hsts

    最近刚刚将一个项目设置为HTTP与HTTPS共存,在这过程中对Rails的配置项force_ssl有了更深的理解。...

  • 加密基础知识三 TLS/SSL HTTPS

    参考SSL/TLS协议运行机制的概述图解SSL/TLS协议 一、作用 不使用SSL/TLS的HTTP通信,就是不加...

  • SSL/TLS协议简介

    阅读阮一峰博客《SSL/TLS协议运行机制的概述》和《图解SSL/TLS协议》摘录 作用 不使用SSL/TLS。 ...

网友评论

      本文标题:PRO-007:理解SSL过程与机制

      本文链接:https://www.haomeiwen.com/subject/ohqodqtx.html