OpenSSL

知识共享许可协议
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

本文系马哥Linux学习笔记整理而成

上一章节“Linux服务与安全基础知识”时,我们提到了加密会话,也就是SSLsecurity socket layer)会话
简单来说,SSL会话主要分三步;我就不再画图了(画了很久,不堪入目)

  • 1.客户端向服务端请求并验证此证书
  • 2.双方协商生成“会话密钥”
  • 3.双方采用“会话密钥”进行加密通信

SSL handshake protocol 顾名思义,这是一个握手协议;握手过程是怎么样的呢?这里面分为几个阶段
####+ 第一阶段:client say hello to server

  • 向服务器发送自己支持的协议版本,比如TLS1.2,支持的加密算法,比如AESRSA
  • 客户端生成一个随机数,稍后用于生成“会话密钥”

####+ 第二阶段:server say hello to client

  • 确认使用的加密通信协议版本,比如TLS1.2;如果不一致则会话就此中断;然后确认使用的加密方法;
  • server生成一个随机数,稍后用于生成“会话密钥”
  • serverclient发送服务器证书

####+ 第三阶段:

  • client验证server证书;主要验证下面的内容
    • 验证发证机构、证书完整性、证书持有者、证书有效期、吊销列表......确认无误后取出其公钥
  • 然后发送以下信息给服务器:
  • 一个随机数:用于服务器上的公钥加密
  • 编码变更通知:表示随后的信息都将使用双方商定的加密方法和密钥发送
  • 客户端握手结束通知

####+ 第四阶段:

  • server收到client发来的第三个随机数后,计算生成本次会话所有用到的“会话密钥”
  • 向客户端发送如下信息
  • 编码变更通知;表示随后的信息都将使用双方商定的加密方法和密钥发送
  • 服务端握手结束通知

需求催生了对应产业,因此对应的服务和基础设施诞生,这就有了PKI!何为PKI

PKIpublic key infrastructure即公钥基础设施;由以下部分组成:

  • 签证机构:CA,好比疫情期间的检测核酸机构拥有最终检测权
  • 注册机构:RA,好比医院等地方收集你的样本,然后将试剂盒送去检测机构检测
  • 证书吊销列表:CRL 有点像阴性出院名单
  • 证书存取库

上面所讲的无论是SSL还是TSL都是协议,而具体落实是需要靠程序来实现;这里最典型的例子就是OpenSSL
OpenSSL主要由三部分组成

  • libcrypto 加密解密算法库
  • libssl 实现ssl功能
  • openssl 多用途命令行工具
    其中
  • libcryptolibssl主要由开发者开发程序时调用接口等
  • openssl 多用途命令行工具,这才是我们最常用的功能

openssl拥有众多子命令,分为三类(openssl ?openssl后面跟一个错误命令即可弹出使用帮助窗口)

  • 标准命令
  • 消息摘要命令
  • 加密命令(enc命令)

常用标准命令:enc,ca,req,genrsa
####那么如何使用openssl手动进行对称加密?
可使用工具:openssl enc,gpg,如下所示
[root@10-9-122-130~]#openssl enc -e -des3 -a -salt -in fstab.cliper -out fstab.haha
enter des-ede3-cbc encryption password:
Verifying - enter des-ede3-cbc encryption password:
[root@10-9-122-130~]#cat fstab.haha
U2FsdGVkX19vl4zwtZhiP1kPwPkWPVpizRkNx91BJ5Nk+meppo3a1Bw7Wz8q8Nz2
x5le4/qvpXhQ+gzRFfelTxXXCRiIs6crDg50ibyvZKUdoa5Ya2q94cBUZXn/Wxd8
wgr8pbE40tPOhdfYzsWAoGhQPcXdI4j8cpZsYkNfrKEYNuOkk/8Bwo9Jvyp3IFek
2ghm/n5tIFk+FoK/raWHyV1xe4v5OUc9nGhWcVbp76iZ6cY9dvKzJ9v9rdoX+v2V
CIc17nKz/GwER0JH7vUubG5ghr7UXoaunBHHJk2vryR8VWi65haDMwNRjZNmb9cO
tn8Mt2Bbo+wmFa9fg1U5HLvddW0FUt/cG7uX9GSzKC4j9eEqkEOw6hzA2gLXybQ4
UORvMbh/eRSef0Wy83EDqJCIa59P7+8f6rKYkN2l9gv9v2KC4gYEhH26HqttUkEb

要解密的话,反过来把-e换成-doutin互换即可

####如何单向加密?
可使用工具工具:openssl dgst,md5sum,sha1sum,sha224sumsha家族;如下所示
[root@10-9-122-130~]#openssl dgst -md5 fstab.cliper
MD5(fstab.cliper)= 4c59ef9a8723da194c79a8b81647659d
[root@10-9-122-130~]#md5sum fstab.cliper
4c59ef9a8723da194c79a8b81647659d fstab.cliper

####如何生成用户密码:passwd,openssl passwd
用法:openssl passwd -1 -salt SALT,如下所示:
[root@10-9-122-130~]#openssl passwd -1 -salt 345
Password:
$1$345$PwV2h6DCYQHkh.uP9Lw9H.

####如何生成随机数:spenssl rand

  • openssl rand -base NUM
    [root@10-9-122-130~]#openssl rand -base64 64
    cL1/g6A3zXEAW5iQmTkbnvZycce9V40c/akJtwfMfsh0ocJT3DPM67fl8AsEjFRR
    OpXBO9HxH0hBUnioQxtsvw==

  • openssl rand -hex NUM 同理,不再演示

####如何使用公钥加密:主要分三部分

  • 1.加密解密

  • 算法:RSA,ELGamal

  • 工具:openssl rsault,pgp

  • 2.数字签名

  • 算法:RSA,DSA,ELGamal

  • 3.密钥交换

  • 算法:DH

  • 4.生成密钥

  • 生成私钥 (umask 077;openssl genrsa -out /PATH/TO/PROVATE_KEY_FILE NUM_BITS)
    [root@10-9-122-130~]#(umask 077;openssl genrsa -out ./HAHA 2048)
    Generating RSA private key, 2048 bit long modulus
    .....................................+++
    .......+++
    e is 65537 (0x10001)

  • 提取公钥 openssl rsa -in /PATH/FROM/PROVATE_KEY_FILE -pubout
    [root@10-9-122-130~]#openssl rsa -in HAHA -pubout
    writing RSA key
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3bCgV8B+0mpsm2tbDxiW
    rAy14L2AolSi9hi1E45eGKd9uuSbggbZe8QHuoy/lSeBSyps+PdG7+jCeAL0Jut5
    h+qjg0FQonvXs70urcuN2XKl21dEb37tQVVqL34543BvEwwFmpMv30xoeZhJ2Mkt
    yk1ec3jfJMVnguNV8+9uhWNSr1nK6mj4/5kajCAZOscPinFyDmQLazwcIm32ArMH
    p2xti4vbkb+0mcu94F54u1erKb7hHn4E6inuZiqHQfvnVLBjmTrX1K9rrRvfJXe/
    9yYd+wydmHyysFMoS4pUOy0HAPPc2VFRWi5cI9VvBDy0yqKiYhDmOpyKEgPwc/MQ
    BwIDAQAB
    -----END PUBLIC KEY-----

上面的握手协议提到很多次随机数,那么在Linux上是如何生成随机数的?

Linux系统上的随机数生成器:主要分两种,硬件和软件

  • 硬件:/dev/random 仅从熵池返回随机数;随机数用完,则阻塞后来的进程

熵池的概念就不用深究了,我们只需要知道熵池是内核在内存空间存储了大量随机数;其中的随机数的来源,比如说
硬盘IO中断时间间隔;就是读写数据的时间间隔,你预测给我看一下?几乎是不可能的,因此安全系数非常高
键盘IO中断时间间隔,两次击键的时间间隔;同上

  • 软硬件:/dev/urandom 从熵池返回随机数;随机数用完,则利用软件生成伪随机数,并非阻塞后来的程序

用软件生成的随机数,再怎么随机都是有一定规则可循,因此并非很安全

再回过头来说说CA,它分两类

  • 公共信任CA:比如全球各大认证机构;可理解成你的护照,全球可签证使用!
  • 私有CA,可理解成你的身份证,只在中国有效!
  • 其实私有CA用的最多的例子,就是银行。比如说U盾等;不可能拿建行的U盾来解你工行的盾吧?那还得了!

###下面说说如何构建私有CA
####构建私有CAopenssl命令配置文件位置:/etc/pki/tls/openssl.cnf

  • 在确定配置为CA的服务器上生成一个自签证书,并为CA提供所需要的目录及文件即可
    ####步骤
    #####1.生成私钥,默认存储位置在/etc/pki/CA/private/cakey.pem,如下所示
    [root@10-9-122-130~]#(umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
    Generating RSA private key, 4096 bit long modulus
    ................................................................................................++
    ...................................................................................................................................................................................................................................................................................................................................................................................................................................++
    e is 65537 (0x10001)
    #####2.生成自签证书,如下所示
    [root@10-9-122-130~]#openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3655
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.

    Country Name (2 letter code) [XX]:CN
    State or Province Name (full name) []:GuangDong
    Locality Name (eg, city) [Default City]:GuangZhou
    Organization Name (eg, company) [Default Company Ltd]:TestCompany
    Organizational Unit Name (eg, section) []:Ops
    Common Name (eg, your name or your server's hostname) []:Test
    Email Address []:cert@test.com

简单说说里面用到的几个选项

  • -new 生成新证书部署请求
  • -509 生成自签格式证书,专用于创建私有CA
  • -key 生成请求时用到的私有文件路径
  • -out 生成的请求文件路径;如果自签操作将直接生成签署过的证书
  • -days 证书有效时长,单位是天

#####3.为CA提供所需的目录及文件,一般来说都是自动创建好的;如果没有则需要自行创建以下目录及文件

  • 三个文件夹 /etc/pki/CA/certs,crl,newcerts
  • 三个文件 /etc/pki/CA/serial,index,txt
  • 然后给它写上第一个标记,执行命令 echo 01 > /etc/pki/CA/serial

#####4.要用到证书进行安全通信的服务器,需要向CA请求签署证书:
步骤:以httpd为例

  • 1)用到的证书的主机生成私钥

  • mkdir /etc/httpd/ssl

  • cd /etc/httpd/ssl

  • (umask 077;openssl genrsa -out httpd.key 2048)

  • 2)生成证书签署请求

  • openssl req -new -key /etc/httpd/ssl/httpd.key -out /etc/httpd/ssl/httpd.csr -days 365

  • 3)将请求通过可靠方式发送给CA主机,如果是内网机器,可使用scp命令即ssh copy

  • 4)在CA主机上签署证书

  • openssl ca -in /PATH/FROM/CSR_FILE -out /etc/pki/CA/certs/httpd.crt -days 365

查看证书中的信息

  • openssl x509 -in /etc/pki/CA/certs/httpd.crt -noout -serial -subject

  • 5)从CA通过可靠方式发送给请求主机,同上;

#####吊销证书:
步骤:

  • 1)客户端获取要吊销的证书的serial(在使用证书的主机执行)

  • openssl x509 -in /etc/pki/CA/certs/httpd.crt -noout -serial -subject

  • 2)CA主机吊销证书

先根据客户端提交的serialsubject信息,对比本机数据库index.txt中存储是否一致

  • 吊销可执行以下命令
  • openssl ca -revoke /etc/pki/CA/newcerts/SERIAL.pem

其中的SERIAL要换成证书真正的序列号

  • 3)生成吊销证书的吊销编号(仅在第一次吊销证书时执行)
  • echo 01 > /etc/pki/CA/crlnumber
  • 4)更新证书吊销列表
  • openssl ca -gencrl -out thisca.crl
  • 查看crl文件
  • openssl crl -in /PATH/FROM/CRL_FILE.crl -noout -text
世间微尘里 独爱茶酒中