openssl原理與實戰
阿新 • • 發佈:2020-12-06
第1章 openssl
1.1 元件
a、libcrypto,libssl主要由開發者使用
b、openssl:多用途命令列工具
[root@shiyanji ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
1.2 命令
a、眾多子命令,大體分為三類,可用openssl ? 來顯示 1)標準命令(Standard commands):每一個命令都使用命令自身來呼叫 2)訊息摘要命令(Message Digest commands):使用dgst命令來呼叫 3)加密命令(Cipher commands):使用enc命令來呼叫 b、標準命令:enc,ca,req,genrsa,...
1.3 基於openssl完成對稱加密
a、工具:openssl enc,gpg等 b、支援的演算法:3des,aes,blowflsh,towflsh c、enc命令,可以使用whatis enc命令檢視 [root@shiyanji ~]# whatis enc enc (1ssl) - symmetric cipher routines (1)加密/etc/fstable檔案中的內容 [root@shiyanji ~]# openssl enc -e -des3 -a -salt -in /etc/fstab -out fstab.ciphertext enter des-ede3-cbc encryption password: Verifying - enter des-ede3-cbc encryption password: 解釋 上述命令的意思是使用openssl enc命令, -e: 表示進行加密(如果解密需要-d引數) -des3: 表示使用des3演算法進行加密 -a: 表示使用base64的編碼格式,文字編碼,即編碼為文字,看上去就是一大推亂碼,如果不加-a就表示預設使用二進位制編碼。 -salt: 表示加一些雜誌進去,至於要怎麼加不用管。 -in /etc/fstab: 表示加密/etc/fstab檔案中的內容 -out fstab.ciphertext: 表示加密後的檔案儲存在fstab.ciphertext檔案中,接下來會讓輸入密碼,可以看到他是用des-ede3-cbc進行加密的 a. 接下來檢視這個檔案 [root@shiyanji ~]# cat fstab.ciphertext U2FsdGVkX1/t8hNBuwrEGag7xNzQZflgEjA/nsbJRMQ80dgcwKf6RREo9TEYRhWl wuvfHpkdJHj11XZ/YAnoSexL0U2xhLACHUIcwrlypj7ENjfoMh9FiG2aqlksNVEv w7wkZzH29bYCPWOJgUpexfR6efH0WjZH+HQh2cSnsr81Omn3i/CX7QORswRLZG/C jPyJtM5087ET3BuoYoVP1LIu5kQbG7mUOlH5aiQIcWC0Yylem1lBOJ7lXRyQCz/E vfXSbhphoo9mNfqnA2OCSZ94d7rWg1zL2PdElZi26azfC2WcKvLhG0bTgudCkWks DKtLAjHTy63Xr35LXUJlQdNkDrSi20geOF04mlyrAdIdb8bEjrB33068GfTFkvzV kqVerMJY/ZiRUC1NIptmUvKUufhCTMCPtDX4QRQi1hG+fwYDdKiqjoWSjDlXI7NP KGEkY98KFRxrDgsJNcY1xHuvfx2H4dMvcK67+b77jcQYxdavCw6oEXdHXuAyDRw0 nknHgyc3HiYCXzTVEijJrv5Ir65QSzctGEXIRv5snTlaQ0GkjVAelrBvBpMv1twX JbynYIkChoIVEbmgUhx9/lBx8Qngz9oNm35za2FWfGDeQQE2td9QakltRcSsIjjg wpwWpcON+zES0FC2FdzqUVVx1vm1kLExxe0qppBzYRjUOs0JGaJnZw== (2) 接下來來解密這個檔案,解密和剛剛過程一樣,只是把-e換成-d,-in和-out對調 [root@shiyanji ~]# ls anaconda-ks.cfg bianyi fstab.ciphertext [root@shiyanji ~]# openssl enc -d -des3 -a -salt -in ./fstab.ciphertext -out ./fstab enter des-ede3-cbc decryption password: [root@shiyanji ~]# ls anaconda-ks.cfg bianyi fstab fstab.ciphertext [root@shiyanji ~]# cat fstab # # /etc/fstab # Created by anaconda on Sat Mar 7 13:05:16 2020 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=ac6edd9a-8b57-4b20-b1d8-e819dcf0bbaf / xfs defaults 0 0 UUID=fb4ef11d-89e8-462b-822f-cd367570413b /boot xfs defaults 0 0 UUID=1b710427-4470-468c-9eac-bb37aad84c3c swap swap defaults 0 0
1.4 基於openssl完成單向加密
a、工具:openssl dgst,md5sum,sha1sum,sha224sum,... b、dgst命令:openssl dgst -md5 /PATH/TO/SOMEFILE [root@shiyanji ~]# ls anaconda-ks.cfg bianyi fstab fstab.ciphertext 計算檔案特徵碼 [root@shiyanji ~]# md5sum fstab 68e9ea4409f367ccb5f4444ab65dd806 fstab 用openssl計算特徵碼 [root@shiyanji ~]# openssl dgst -md5 fstab MD5(fstab)= 68e9ea4409f367ccb5f4444ab65dd806 可以看到,輸出的方式雖然不一樣,但是計算出來的特徵碼是一樣的,因為都是用的md5演算法
1.5 公鑰加密
a、加密
1)演算法:RSA,ELGamal
2)工具:openssl rsautl,gpg
b、數字簽名
1)演算法:RSA,DSA,ELGamal
2)工具:openssl rsautl,gpg
c、金鑰交換
1)演算法:DH,RSA也支援
1.6 生成金鑰
(1) 生成私鑰:要想完成公鑰加密技術加密資料首先我們要生成金鑰對,如果去獲取金鑰對就變得比較關鍵了
openssl 有個子命令叫openssl genrsa或openssl gendsa,可以通過openssl genrsa指明要生成多少位的金鑰,他的金鑰位數支援
512,768,1024,2048,4096等,必須是2的n次方倍的位數。所以只能是上述的這種位數
(umask 077;openssl genrsa -out /PATH/TO/PRIVATE_KEY_FILE NUM_BITS)
1)生成一個1024位的金鑰
[root@shiyanji ~]# openssl genrsa 1024
Generating RSA private key, 1024 bit long modulus
......................++++++
..............................++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQDkCASx2V9ZKFhKHvSXdyLBdKwLPdNgbCUSptfI8+tsEjBHXkPH
9lu4B4DgK9WgOLARlgDnhVeI1IiqyweOTD6LlOkhu7AjGIfh4o/a09Kf42DzAOvJ
LI5LRRsZA7eGOTLr/mMDbH5LwzB53lvuhf/09zDKRFtO8FqfWZ3CZUTxhwIDAQAB
AoGBAJyFqHtPovQ3Dktqbifdvfyekk1xFbuU3+mqnmmwjIN1BLCoUsxaHWD3vY2i
aRN+ddTMaziAPbKNeHYLwNb7HN41FQXEv18GDREmNkJ+NeeKLsIebox921aNJsn5
NRExX5GhlMdbxlripBeNgy4l9xuiFEIGrKOxka62kJ5JtKLZAkEA9GZjQGBN3mRL
4a9otF2mNZ9oyT/Rk9UCozyAA/uKPvVQG5IpQQmGnC7S3s77Z1pMrO3cilAjbT3L
Cir3hvwajQJBAO7avdWRIVslIfjvjndMMlGRvE/3tM6lGhQyCnqcCiUiKv3IOa+6
i/ohCTHr1vvP9ZNZTGqFwj+eJShuNN5koWMCQQC93UDjxS0ZRO+ST3PXEx3JcKK2
HYcSApw+9gQ5k9NtX6QxFxZHeUAC23lkMIYsX4FLoqn/JYywFB5FMuYDDp0NAkEA
kfJs3ouAkz3cRUyzg6e2c2sWYtKb00zE46Q0DPk9pbT8CfgHb54QG/WFtdBCm7lV
eASvkcNLjy3lzI+SlHVuuwJBAKHTjM31+QOCLtyo5882Ei+LrbcDcsm9HZjsBIth
umoaRRGL7K20f2L/9Hoe3WWUQ9Km7faJIDqvuOeCl7niXAM=
-----END RSA PRIVATE KEY-----
可以看到,生成的是一個私鑰,公鑰是從私鑰中提取出來的。也可以將這個金鑰對儲存下來,可以通過輸出重定向或者-out引數
[root@shiyanji ~]# openssl genrsa 1024 > /tmp/mykey.private
[root@shiyanji ~]# ls -l /tmp/mykey.private
-rw-r--r-- 1 root root 887 Dec 6 15:02 /tmp/mykey.private
可以看到檔案所有使用者都是有讀許可權的,即私鑰能被其他人讀取,因此任何時候生成的私鑰都應該改為僅自己能讀能寫,因此可以通過這種方式來進行建立
[root@shiyanji ~]# (umask 077;openssl genrsa -out /tmp/mykey3.private 2048)
[root@shiyanji ~]# ls -l /tmp/mykey3.private
-rw------- 1 root root 1679 Dec 6 15:03 /tmp/mykey3.private
可以看到通過這種方式創建出來的檔案許可權為600,即只有自己可以讀寫。
使用括號括起來表示在子shell中執行,在子shell中設定umask為077然後第二個命令也就受子shell影響了,等結束後回到主程序父shell umask是不變的
(2) 提出公鑰。一般不需要自己提,介紹方法
[root@shiyanji ~]# openssl rsa -in /tmp/mykey3.private -pubout -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4VLGe2jodB9ANDADYGld
rN31h8B0s/Qs/80oXcbPt+Sr0Q4sSpYWnSw1FlZNmN+JcYDS9IOQvbHFjWpy/UpV
wJ0GMQKKabo48M02SZeHpUHAlS48Kc3XGbvz75T8RPjff14lpZiNib8L0NmIA7ja
ATqVuDkYqxf0vlUYDnNyWCQ3bJgdqWpFxa5KAIUrxJ9xn/xyqtzAHyBNK5Z5VXir
GbWc++U41EkuaFUt2zu/JuP0456m4NgaPtJU5Ov7A4imA5c1pS5UEd0+qi2/IwYu
/I5BaCf0Ili8bihn5hE55hCDVxuKAv8p4BduukMZdeG77K0hXr9FpyYAUDeNYzUC
JQIDAQAB
-----END PUBLIC KEY-----
1.7 Linux系統上的隨機數生成器
不管是用的什麼演算法,都嚴重依賴隨機數
a、/dev/random:僅從熵池返回隨機數,隨機數用盡,阻塞
b、/dev/urandom:從熵池返回隨機數,隨機數用盡,會利用軟體生成偽隨機數,非阻塞。但是偽隨機數是不安全的
c、熵池中的隨機數來源:熵池就是執行中的核心在記憶體中維護的一段空間,這段空間中儲存了大量的隨機數,不過剛啟動時是空的。他的來源一般有兩種
1)硬碟IO中斷時間間隔
2)鍵盤IO中斷時間間隔,獲取隨機數的時候不是複製,而是剪下,如果取的隨機數多餘生成的隨機數隨機數就被耗盡了。
3)所以隨機數取的時候被阻塞就猛著敲鍵盤,或者複製檔案,這種操作會有大量的磁碟IO
第2章 自建CA
2.1 概述
1、公共信任CA,私有CA
2、建立私有CA:
a、openssl
b、OpenCA:一個開源的CA工具,其實其底層也是用的opensll,只是使用起來更簡單了
3、openssl命令
a、配置檔案 /etc/pki/tls/openssl.cnf。
這個配置檔案中為openssl扮演一個CA管理工具提供了相關配置,可以在[ca]這個欄位中檢視
2.2 /etc/pki/tls/openssl.cnf解釋
[root@www openssl]# cat /etc/pki/tls/openssl.cnf |grep -Ev "^#|^$"|grep -wA22 ca
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
dir = /etc/pki/CA #Where everything is kept,即作為CA的預設工作目錄
certs = $dir/certs # Where the issued certs are kept,用來放簽發過的證書的位置
crl_dir = $dir/crl # Where the issued crl are kept,用來存放吊銷的證書
database = $dir/index.txt #database index file. #資料庫檔案,存放了已經頒發過的證書的索引
# several ctificates with same subject.
new_certs_dir = $dir/newcerts #default place for new certs.
certificate = $dir/cacert.pem #The CA certificate #CA的自簽證書
serial = $dir/serial #The current serial number #指明當前序列號碼,用來為當前主機上每一個證書提供序列號
crlnumber = $dir/crlnumber #the current crl number #為當前主機上每一個吊銷的證書提供序列號
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem #The current CRL
private_key = $dir/private/cakey.pem# The private key #指CA自己的私鑰
RANDFILE = $dir/private/.rand #private random number file
x509_extensions = usr_cert #The extentions to add to the cert
name_opt = ca_default #Subject Name options
cert_opt = ca_default #Certificate field options
default_days = 365 #how long to certify for #證書的預設有效期
default_crl_days= 30 #how long before next CRL
default_md = sha256 #use SHA-256 by default #預設訊息摘要演算法是sha256
preserve = no #keep passed DN ordering
policy = policy_match
2.2 構建私有CAb步驟
第一個里程:生成私鑰;預設放在/etc/pki/CA/private/目錄下
(umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
[root@shiyanji ~]# (umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
Generating RSA private key, 4096 bit long modulus
.........................++
......++
e is 65537 (0x10001)
第二個里程:生成自簽證書
[root@shiyanji ~]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3656
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) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:ceshi
Organizational Unit Name (eg, section) []:ops
Common Name (eg, your name or your server's hostname) []:ca.ceshi.com
Email Address []:
[root@shiyanji ~]# ll /etc/pki/CA/
total 4
-rw-r--r-- 1 root root 2009 Dec 6 15:14 cacert.pem
drwxr-xr-x. 2 root root 6 Aug 9 2019 certs
drwxr-xr-x. 2 root root 6 Aug 9 2019 crl
drwxr-xr-x. 2 root root 6 Aug 9 2019 newcerts
drwx------. 2 root root 23 Dec 6 15:11 private
上述/etc/pki/CA/目錄下的其它目錄如果存在不用管它如果不存在需要手動建立
1)我們上述命令解釋如下:
-new:表示生成一個新請求
-x509:如果是自簽證書就需要加此引數
-key:表示私鑰在什麼地方(因為證書中的公鑰是在私鑰中提取的)
-out:指明證書儲存在什麼地方,/etc/pki/CA/目錄是固定位置
-days:指明證書的有效期限是多少天,預設是365天,這兒指明的是10年
2)需要輸入的內容
Country Name:兩個字元的國家程式碼,此處CN,即中國
State or Province Name:在哪個州,此處寫的Beijing
Locality Name:在哪個城市,此處寫的Beijing
Organization Name:公司名字,此處的是ceshi
Organizational Unit Name:部門名稱,此處寫的是運維部,即Ops
Common Name:證書持有者自己的人名或證書所在的伺服器的名字,
Email Address:管理員郵箱,
第三個里程:為CA提供所需的目錄及檔案
1)建立目錄
mkdir /etc/pki/CA/{certs,crl,newcerts}
2)建立檔案
touch /etc/pki/CA/{serial,index.txt}
[root@shiyanji ~]# ll /etc/pki/CA/
total 4
-rw-r--r-- 1 root root 2009 Dec 6 15:14 cacert.pem
drwxr-xr-x. 2 root root 6 Aug 9 2019 certs
drwxr-xr-x 2 root root 6 Dec 6 15:18 {certs,crl,newcerts}
drwxr-xr-x. 2 root root 6 Aug 9 2019 crl
-rw-r--r-- 1 root root 0 Dec 6 15:19 index.txt
drwxr-xr-x. 2 root root 6 Aug 9 2019 newcerts
drwx------. 2 root root 23 Dec 6 15:11 private
-rw-r--r-- 1 root root 0 Dec 6 15:19 serial
3)serial檔案不能為空因此可以重定向一個數據進去
echo 01 > /etc/pki/CA/serial
第四個里程:要用到證書進行安全通訊的伺服器,需要向CA請求籤署證書
a. 步驟
1)這個步驟需要在要用到證書進行安全通訊的伺服器上面,
假如現在有一臺伺服器node2中有httpd服務,然後進入到相應的httpd目錄中建立ssl目錄,在目錄中生成相應的私鑰和對應的證書籤署請求
並將公鑰發給CA伺服器www請求證書
1)建立相應的資料夾
[root@node2 ~]# mkdir /etc/httpd/conf/ssl
[root@node2 ~]# cd /etc/httpd/conf/ssl
[root@node2 ssl]# ls
2)生成私鑰
[root@node2 ssl]# (umask 077;openssl genrsa -out /etc/httpd/conf/ssl/httpd.key 2048)
Generating RSA private key, 2048 bit long modulus
...................................................+++
............................................+++
e is 65537 (0x10001)
[root@node2 ssl]# ll
total 4
-rw------- 1 root root 1679 Apr 20 05:34 httpd.key
3)生成證書籤署請求
[root@node2 ssl]# openssl req -new -key /etc/httpd/conf/ssl/httpd.key -out /etc/httpd/conf/ssl/httpd.csr -days 365
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) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:wohaoshuai
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:www.ceshi.com
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
上述-out 引數後的/etc/httpd/ssl/httpd.csr檔案即為簽署請求
下面讓輸入的內容中www.ceshi.com這個內容一般是網際網路訪問主機的域名,訪問時也必須嚴格按照此名字否則證書不通過
最後兩行的密碼敲enter即可
4)然後把httpd.csr這個證書籤署請求發給CA伺服器www讓其給簽署一下,下面是www伺服器的操作
首先拷貝node2伺服器上的證書籤署請求
[root@www /]# scp [email protected]:/etc/httpd/conf/ssl/httpd.csr /application/
[email protected]'s password:
httpd.csr
[root@www /]# ll /application/httpd.csr
-rw-r--r-- 1 root root 1066 4月 20 05:45 /application/httpd.csr
然後開始簽署
root@www /]# openssl ca -in /application/httpd.csr -out /etc/pki/CA/certs/httpd.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Apr 19 21:49:21 2020 GMT
Not After : Apr 19 21:49:21 2021 GMT
Subject:
countryName = CN
stateOrProvinceName = Beijing
organizationName = wohaoshuai
organizationalUnitName = Ops
commonName = www.wohaoshuai.com
emailAddress = [email protected]
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
A3:69:40:E3:BA:9A:31:C7:B4:83:D1:A9:E6:66:F1:4B:6B:3D:CB:66
X509v3 Authority Key Identifier:
keyid:0F:8F:62:47:89:2E:2F:AD:3D:B0:FD:79:E9:C8:A7:57:B2:23:74:1C
Certificate is to be certified until Apr 19 21:49:21 2021 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
注意簽署後的證書是httpd.crt,開始證書籤署請求的名字是httpd.crs。後面兩個詢問是問你籤不籤,並且確認籤不籤,輸入y即可
然後來看此時的database檔案
[root@www /]# cat /etc/pki/CA/index.txt
V 210419214921Z 01 unknown /C=CN/ST=Beijing/O=wohaoshuai/OU=Ops/CN=www.ceshi.com/[email protected]
V表示已經簽過的。01是序列號,最後這一段是subject,是主題資訊,也叫主題標識
5)然後把簽好了的證書傳送給node2
[root@www /]# scp /etc/pki/CA/certs/httpd.crt [email protected]:/etc/httpd/conf/ssl/
[email protected]'s password:
httpd.crt
b、總結(以httpd為例)
1)用到證書的主機生成私鑰
mkdir /etc/httpd/conf/ssl
cd /etc/httpd/conf/ssl
(umask 077;openssl genrsa -out /etc/httpd/conf/ssl/httpd.key 2048)
2)生成證書籤署請求
openssl req -new -key /etc/httpd/conf/ssl/httpd.key -out /etc/httpd/conf/ssl/httpd.csr -days 365
3)將請求通過可靠方式傳送給CA主機
scp [email protected]:/etc/httpd/conf/ssl/httpd.csr /application/
4)在CA主機上籤署證書
openssl ca -in /application/httpd.csr -out /etc/pki/CA/certs/httpd.crt -days 365
1) 檢視證書中的資訊,可以通過引數檢視相應的欄位內容,此處只檢視序列號和subject資訊
[root@node2 ssl]# openssl x509 -in httpd.crt -noout -serial -subject
serial=01
subject= /C=CN/ST=Beijing/O=ceshi/OU=Ops/CN=www.ceshi.com/[email protected]
吊銷證書
a、步驟
1)客戶端獲取要吊銷的證書的serial(在使用證書的主機上執行);
[root@node2 ssl]# openssl x509 -in httpd.crt -noout -serial -subject
serial=01
subject= /C=CN/ST=Beijing/O=wohaoshuai/OU=Ops/CN=www.wohaoshuai.com/[email protected]
2)在CA上執行,CA主機吊銷證書
1)先根據客戶端提交的serial和subject資訊,對比本機資料庫index.txt中儲存的是否一致
2)吊銷
[root@www /]# openssl ca -revoke /etc/pki/CA/newcerts/01.pem
其中的01.pem即serial.pem,也就是相應httpd.crt證書的序列號,證書建立時該序列號就有了
3)生成吊銷證書的吊銷編號(第一次吊銷證書時執行)
echo 01 > /etc/pki/CA/crinumber
4)更新證書吊銷列表
openssl ca -gencrl -out thisca.crl
5)檢視crl檔案
openssl crl -in /PATH/FROM/CRL_FILE.crl -noout -text