1.理論知識
https簡介
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer)愧捕,是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層林束,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。
超文本傳輸協(xié)議HTTP協(xié)議被用于在Web瀏覽器和網(wǎng)站服務(wù)器之間傳遞信息。HTTP協(xié)議以明文方式發(fā)送內(nèi)容坎拐,不提供任何方式的數(shù)據(jù)加密,如果攻擊者截取了Web瀏覽器和網(wǎng)站服務(wù)器之間的傳輸報(bào)文养匈,就可以直接讀懂其中的信息哼勇,因此HTTP協(xié)議不適合傳輸一些敏感信息,比如信用卡號呕乎、密碼等积担。
為了解決HTTP協(xié)議的這一缺陷,需要使用另一種協(xié)議:安全套接字層超文本傳輸協(xié)議HTTPS猬仁。為了數(shù)據(jù)傳輸?shù)陌踩坭担琀TTPS在HTTP的基礎(chǔ)上加入了SSL協(xié)議,SSL依靠證書來驗(yàn)證服務(wù)器的身份湿刽,并為瀏覽器和服務(wù)器之間的通信加密的烁。
HTTPS和HTTP的區(qū)別主要為以下四點(diǎn):
https協(xié)議需要到ca申請證書,一般免費(fèi)證書很少叭爱,需要交費(fèi)撮躁。
http是超文本傳輸協(xié)議漱病,信息是明文傳輸买雾,https 則是具有安全性的ssl加密傳輸協(xié)議。
http和https使用的是完全不同的連接方式杨帽,用的端口也不一樣漓穿,前者是80,后者是443注盈。
http的連接很簡單晃危,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議僚饭,比http協(xié)議安全震叮。
簡單的說,https就是在http的基礎(chǔ)上嵌套SSL協(xié)議鳍鸵,由此來實(shí)現(xiàn)身份認(rèn)證苇瓣,要理解SSL,還要說明一下非對稱加密體系偿乖。
對稱加密:指的是加密和解密使用的是同一個(gè)密鑰击罪,發(fā)送者使用秘鑰A對信息加密,然后傳送密文贪薪,接受者使用密鑰A對密文解密媳禁,得到信息。若此時(shí)使用密鑰B解密此密文画切,則無法進(jìn)行解密竣稽。為了保證加密的可靠性,發(fā)送者和接受者都要保證密鑰A不被泄露霍弹。
非對稱加密:使用一對密鑰進(jìn)行加密和解密操作丧枪,分別稱為公鑰和私鑰,公鑰和私鑰是成對生成的庞萍,公鑰往往是公開的拧烦,任何人都可以得到,私鑰是保密的钝计,只有特定的人才擁有恋博。非對稱加密有兩種典型的使用情況,分別是加密和驗(yàn)證私恬。
下面簡單介紹加密與驗(yàn)證债沮。
- 加密:
加密是為了傳送需要保密的信息,所以需要保證只有特定的人才可以對信息進(jìn)行解密本鸣。
發(fā)送者使用公鑰A加密疫衩,接受者使用私鑰A解密。假設(shè)所有人都擁有公鑰A荣德,只有張三有私鑰A闷煤,那么,其他人想要給張三發(fā)送信息涮瞻,只需要將信息使用公鑰A加密鲤拿,那么密文只有擁有私鑰A的張三才可以解密。
- 驗(yàn)證:
驗(yàn)證是為了向其他人證明“我就是我”的問題署咽。
在這里近顷,發(fā)送者使用私鑰進(jìn)行A簽名,接受者使用公鑰A進(jìn)行驗(yàn)證。還是假設(shè)所有人都擁有公鑰A窒升,只有張三有私鑰A缀遍,現(xiàn)在張三要向其他人證明自己就是張三,于是張三將“我是張三”這段信息使用私鑰A進(jìn)行簽名饱须,發(fā)送給其他人瑟由,其他人使用公鑰A解密,得到簽名“我是張三”冤寿,于是其他人就認(rèn)為這段信息是張三發(fā)送的歹苦。
這里有一個(gè)問題,就是任何人都可以使用自己的私鑰將“我是張三”簽名督怜,從而仿冒張三殴瘦,假設(shè)此時(shí)有一個(gè)李四,他用自己的私鑰B簽名“我是張三”号杠,這使其他擁有公鑰B的人會認(rèn)為李四就是張三蚪腋。
解決這個(gè)問題的方法就是引入有足夠公信力的第三方,由第三方負(fù)責(zé)驗(yàn)證誰是誰的問題(就像我們使用公安局簽發(fā)的身份證就可以證明自己是自己)姨蟋。張三為了證明自己是張三屉凯,他會將“我是張三”發(fā)送給第三方,第三方用自己的私鑰C將驗(yàn)證信息加密(這就是簽名),將加密后的簽名返回給張三眼溶,以后張三就會使用這個(gè)簽名來證明自己是張三悠砚。其他人只會只用第三方的公鑰對簽名進(jìn)行驗(yàn)證。這是如果李四要仿冒自己是張三堂飞,他用自己私鑰B加密后的驗(yàn)證信息灌旧,其他人用第三方的公鑰C是無法解密的。
在https中绰筛,CA就是這個(gè)第三方枢泰,CA(Certificate Authority),也稱為電子商務(wù)認(rèn)證中心铝噩,是負(fù)責(zé)發(fā)放和管理數(shù)字證書的權(quán)威機(jī)構(gòu)衡蚂,并作為電子商務(wù)交易中受信任的第三方,承擔(dān)公鑰體系中公鑰的合法性檢驗(yàn)的責(zé)任骏庸。CA具體流程下面再說毛甲。
https建立流程
首先上圖,這張圖顯示了https建立的流程敞恋。
下面簡單解釋一下這個(gè)流程:
- CA建立丽啡,并頒發(fā)給自己根證書谋右。即CA使用自己的私鑰硬猫,將CA的驗(yàn)證信息和自己的公鑰打包加密成根證書。
- CA與瀏覽器廠商(browser vendor)聯(lián)系,告訴瀏覽器廠商自己的證書啸蜜,如果瀏覽器廠商信任這個(gè)CA坑雅,就會把這個(gè)CA的證書加入到自己開發(fā)的瀏覽器中。
- 一個(gè)想要獲取https服務(wù)的網(wǎng)站衬横,首先要將自己的驗(yàn)證信息和自己的公鑰發(fā)送給CA裹粤,并向CA申請自己的證書,CA在驗(yàn)證這個(gè)網(wǎng)站的合法性之后蜂林,會用CA自己的私鑰對網(wǎng)站的驗(yàn)證信息和公鑰打包加密遥诉,形成這個(gè)網(wǎng)站的證書,并將這個(gè)證書頒發(fā)給網(wǎng)站噪叙。
- 現(xiàn)在網(wǎng)站已經(jīng)有了自己的證書了矮锈,于是他可以搭建自己的https服務(wù)。
現(xiàn)在一個(gè)客戶端要使用網(wǎng)站的https服務(wù)睁蕾,網(wǎng)站會將自己的證書發(fā)送給客戶端苞笨。客戶端使用CA的證書對網(wǎng)站證書進(jìn)行驗(yàn)證子眶,核實(shí)無誤后建立安全連接瀑凝,即SSL握手過程。 - 由客戶端開始臭杰≡吝洌客戶端發(fā)送SSL版本,以及加密和壓縮算法給服務(wù)器渴杆。服務(wù)器檢查是否支持此版本SSL射窒,并啟動客戶端期望的加密和壓縮算法。
- 基礎(chǔ)配置完畢后将塑,服務(wù)器發(fā)送自己的證書脉顿。該證書必須被客戶端信任,或者被客戶端信任的CA所信任点寥。
- 客戶端驗(yàn)證證書艾疟,并核實(shí)服務(wù)器的身份是正確的。
- 驗(yàn)證完畢后敢辩,兩者協(xié)商之后使用的加密方式蔽莱,并且客戶端告訴服務(wù)器,從現(xiàn)在起戚长,所有數(shù)據(jù)互換都是加密的盗冷,并發(fā)送一個(gè)加密的驗(yàn)證”消息“給服務(wù)器。
服務(wù)器驗(yàn)證是客戶端發(fā)送的同廉,并且”消息“可以被解密仪糖。服務(wù)器將解密后的”消息“發(fā)送給客戶端柑司。客戶端核實(shí)后锅劝,安全連接攒驰。握手結(jié)束。
- 驗(yàn)證完畢后敢辩,兩者協(xié)商之后使用的加密方式蔽莱,并且客戶端告訴服務(wù)器,從現(xiàn)在起戚长,所有數(shù)據(jù)互換都是加密的盗冷,并發(fā)送一個(gè)加密的驗(yàn)證”消息“給服務(wù)器。
- 之后故爵,客戶端和服務(wù)器可以使用https服務(wù)進(jìn)行加密通信了玻粪,不過之后的通信一般使用對稱加密算法來實(shí)現(xiàn),因?yàn)橄噍^于非對稱加密诬垂,對稱加密所占資源更少劲室。
2.搭建https服務(wù)
本機(jī)環(huán)境:Ubuntu 18.04.3 LTS , Openssl 1.1.1 , FireFox68.0.1(64 位) , Apache 2.4.29
首先確認(rèn)安裝OpenSSL
openssl version
如果版本低于1.0.1f,建議升級结窘,因?yàn)?.0.1f版本之下的OpenSSL有一個(gè)Heartbleed漏洞痹籍。
安裝OpenSSL:
sudo apt install openssl
自建CA
因?yàn)橄駽A申請簽名是需要收費(fèi)的,所以我們選擇自己搭建一個(gè)CA來完成這個(gè)實(shí)驗(yàn)過程晦鞋。
首先建立myCA目錄用于存放CA相關(guān)信息
cd && mkdir -p myCA/signedcerts && mkdir myCA/private && cd myCA
myCA 用于存放 CA 根證書蹲缠,證書數(shù)據(jù)庫,以及后續(xù)服務(wù)器生成的證書悠垛,密鑰以及請求
signedcerts:保存簽名證書的 copy
private: 包含私鑰
之后配置myCA相關(guān)參數(shù)线定,在myCA目錄下進(jìn)行
echo '01'>serial && touch index.txt
然后創(chuàng)建 caconfig.cnf 文件
vim ~/myCA/caconfig.cnf
caconfig.cnf文件內(nèi)容如下
# My sample caconfig.cnf file.
#
# Default configuration to use when one is not provided on the command line.
#
[ ca ]
default_ca = local_ca
#
#
# Default location of directories and files needed to generate certificates.
#
[ local_ca ]
dir = /home/<username>/myCA # 這里要將username替換為你的用戶名
certificate = $dir/cacert.pem
database = $dir/index.txt
new_certs_dir = $dir/signedcerts
private_key = $dir/private/cakey.pem
serial = $dir/serial
#
#
# Default expiration and encryption policies for certificates.
#
default_crl_days = 365
default_days = 1825
default_md = SHA256
#
policy = local_ca_policy
x509_extensions = local_ca_extensions
#
#
# Default policy to use when generating server certificates. The following
# fields must be defined in the server certificate.
#
[ local_ca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = supplied
organizationName = supplied
organizationalUnitName = supplied
#
#
# x509 extensions to use when generating server certificates.
#
[ local_ca_extensions ]
subjectAltName = DNS:localhost
basicConstraints = CA:false
nsCertType = server
#
#
# The default root certificate generation policy.
#
[ req ]
default_bits = 2048
default_keyfile = /home/<username>/myCA/private/cakey.pem # 這里要將username替換為你的用戶名
default_md = SHA256
#
prompt = no
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions
#
#
# Root Certificate Authority distinguished name. Change these fields to match
# your local environment!
#
[ root_ca_distinguished_name ]
commonName = MyOwn Root Certificate Authority # CA機(jī)構(gòu)名
stateOrProvinceName = JS # CA所在省份
countryName = CN # CA所在國家(僅限2個(gè)字符)
emailAddress = XXXX@XXX.com # 郵箱
organizationName = XXX #
organizationalUnitName = XXX #
#
[ root_ca_extensions ]
basicConstraints = CA:true
生成 CA 根證書和密鑰
export OPENSSL_CONF=~/myCA/caconfig.cnf #該命令用于給環(huán)境變量 OPENSSL_CONF 賦值為caconfig.cnf。注意命令中間不要寫空格
openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825 # 生成 CA 根證書和密鑰
該命令需要用戶設(shè)置密碼确买。不要忘記斤讥。
以上步驟生成了 CA 自簽名根證書,和 RSA 公/私密鑰對湾趾。證書的格式是 PEM芭商,有效期是1825天。
- /myCA/cacert.pem: CA 根證書
- /myCA/private/cakey.pem: CA 私鑰
創(chuàng)建服務(wù)器公私鑰
生成服務(wù)器配置文件exampleserver.cnf
vim ~/myCA/exampleserver.cnf
exampleserver.cnf文件內(nèi)容如下
#
# exampleserver.cnf
#
[ req ]
prompt = no
distinguished_name = server_distinguished_name
[ server_distinguished_name ]
commonName = localhost # 服務(wù)器域名
stateOrProvinceName = JS # 服務(wù)器所在省份
countryName = CN # 服務(wù)器所在國家(僅限2個(gè)字符)
emailAddress = XXXX@XXX.com # 郵箱
organizationName = XXX #
organizationalUnitName = XXX #
生成服務(wù)器證書和密鑰
export OPENSSL_CONF =~/myCA/exampleserver.cnf # 該命令設(shè)置環(huán)境變量 OPENSSL_CONF搀缠,使得 openssl 更換配置文件铛楣。
openssl req -newkey rsa:1024 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM
同樣的,需要輸入密碼短語艺普。
之后簸州,有2種對臨時(shí)秘鑰的操作,選擇其一即可
1.將臨時(shí)私鑰轉(zhuǎn)換為 unencrypted key歧譬,即秘鑰不加密狀態(tài)岸浑。
penssl rsa -in tempkey.pem -out server_key.pem
需要輸入密碼短語。
2.如果希望將 key 保持為加密狀態(tài)瑰步,直接改名
mv tempkey.pem server_key.pem
兩者的區(qū)別是矢洲,第二種需要在服務(wù)器啟動時(shí)輸入私鑰的密碼短語,否則會導(dǎo)致服務(wù)器啟動失敗缩焦,但第二種安全性高于第一種读虏,可以更好的保護(hù)秘鑰责静。
使用 CA key 對服務(wù)器證書簽名
export OPENSSL_CONF=~/myCA/caconfig.cnf
openssl ca -in tempreq.pem -out server_crt.pem
刪除臨時(shí)證書和密碼文件
rm -f tempkey.pem && rm -f tempreq.pem
現(xiàn)在,自簽名的服務(wù)器證書和密鑰對便產(chǎn)生了:
server_crt.pem : 服務(wù)器證書文件
server_key.pem : 服務(wù)器密鑰文件
配置 Apache
建立ssl配置文件掘譬,lab-ssl.conf
vim /etc/apache2/sites-available/lab-ssl.conf
lab-ssl.conf文件內(nèi)容如下
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/lab # 網(wǎng)站目錄
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# 網(wǎng)站證書和私鑰地址
SSLCertificateFile /home/libaoquan/myCA/server_crt.pem
SSLCertificateKeyFile /home/libaoquan/myCA/server_key.pem
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
</IfModule>
啟動ssl服務(wù)
a2ensite /etc/apache2/sites-available/lab-ssl.conf
a2enmod ssl
查看是否正確配置
在瀏覽器地址欄輸入 https://localhost
發(fā)現(xiàn)瀏覽器不信任這個(gè)網(wǎng)站泰演,為什么呻拌?行為這個(gè)網(wǎng)站的證書是用我們自己的CA簽名的葱轩,瀏覽器并不信任我們自己建立的CA,所以我們需要手動導(dǎo)入CA證書讓瀏覽器信任我們的CA藐握。
導(dǎo)入步驟如下:
打開 FireFox 瀏覽器靴拱,依次選擇“編輯”----“首選項(xiàng)”----“隱私與安全”----“證書”----“查看證書”----“證書機(jī)構(gòu)”,點(diǎn)擊導(dǎo)入猾普,選擇 myCA 目錄下的根證書“cacert.pem”, 導(dǎo)入袜炕。
之后,再次瀏覽localhost
地址欄有一個(gè)綠色的鎖初家,至此https服務(wù)搭建完成偎窘。