即使是非對稱加密系統(tǒng),也不能保證公鑰的分發(fā)是可靠的. 為了防范公鑰分發(fā)過程中的中間人攻擊,需要一個可信的"始祖"公證人,這就是CA機構存在的意義.
由CA簽發(fā)證書認證網站的過程
- CA機構生成密鑰對: 公鑰 ca.cer 和 私鑰 ca.key
- 瀏覽器/操作系統(tǒng)攜帶證書ca.cer
- 網站生成私鑰 cert.key
- 網站將公鑰及網站信息(域名/組織等),提交給CA機構
- CA機構使用私鑰ca.key簽發(fā)網站證書cert.cer
- 網站運營商通過cert.key和 cert.cer運行https
- 用戶訪問網站,獲得cert.cer,由于該證書使用CA機構的私鑰簽發(fā),因此可以通過保存在本地的公鑰ca.cer驗證
- 驗證通過并得到了公鑰-> 顯示綠色https標志; 否則,提示用戶風險信息
- 用戶通過公鑰與網站服務器交換對稱加密密鑰,進行正式的SSL會話
通過上述步驟可以看出,只要能保證網站公鑰的可靠性即可,所以如果客戶端直接存放了網站的證書,那么也是可以保證https正常進行的.
但是無論是何種證書,都需要可靠的分發(fā)到客戶端才能保證安全.在開發(fā)過程中我們可能有各種各樣的服務端,相較于為每一個服務端向客戶端分發(fā)證書,還不如直接分發(fā)根證書,這樣只需一次分發(fā),客戶端就可以完成后續(xù)的簽發(fā)過程.
自認證CA根證書生成及簽發(fā)
證書生成過程可以通過openssl完成.為了簡化操作,我寫了一個shell腳本,只需兩步即可生成根證書及使用根證書簽發(fā)網站證書
保存以下代碼為gen_crt.sh,然后按照幫助內容使用即可.
-
生成根證書
./gen_crt.sh root aes128 2048 365 "/CN=MyCA"此時目錄下有ca.key及ca.cer兩個文件,ca.cer需要發(fā)布到客戶端
為了保證私鑰的安全,生成過程中需要一個對ca.key加密的密碼 簽發(fā)網站證書
./gen_crt.sh sign aes128 2048 365 "/CN=www.mysite.com" ca.key ca.cer
為了保證私鑰的安全,生成過程中需要一個對cert.key加密的密碼.
#!/bin/sh
help()
{
echo "Example: ./gen_crt.sh root aes128 2048 365 \"/CN=CustomCA\""
echo "Example: ./gen_crt.sh sign aes128 2048 365 \"/CN=www.mysite.com\" ca.key ca.cer"
echo "key_length: 1024|2048|4096"
methods="aes128|aes192|aes256|camellia128|camellia192|camellia256|des|des3|idea"
echo "Supported encryption methods:" $methods
exit 1
}
operation=$1
method=$2
key_length=$3
expire_days=$4
subj=$5
ca_key=$6
ca_cer=$7
RED="\033[0;31m"
GREEN="\033[0;32m"
NC="\033[0m"
if [ "$operation" = "root" ];then
if [ $# -ne 5 ];then
echo "${RED}Invalid argument num:$#${NC}"
help
fi
elif [ "$operation" = "sign" ];then
if [ $# -ne 7 ];then
echo "${RED}Invalid argument num:$#${NC}"
help
fi
else
echo "${RED}Invalid operation $operation${NC}"
help
fi
echo "Operation" $operation
case $method in
aes128|aes192|aes256|camellia128|camellia192|camellia256|des|des3|idea)
echo "Using cryption method:" $method
;;
*)
echo "Wrong parameters"
help
;;
esac
case $key_length in
1024|2048|4096)
echo "RSA Key length:" $key_length
;;
*)
echo "Wrong RSA key length"
help
;;
esac
if [$expire_days -lt 0]; then
echo "Invalid expire days:" $expire_days
help
fi
if [ "$operation" = "root" ];then
echo "Creating Root CA..."
openssl genrsa -$method -out ca.key $key_length
openssl req -x509 -new -key ca.key -out ca.cer -days 750 -subj $subj
echo "${GREEN}Please distribute ca.cer anywhere needed"
echo "${RED}Please keep ca.key in a private place${NC}"
elif [ "$operation" = "sign" ];then
openssl genrsa -$method -out cert.key $key_length
openssl req -new -out cert.req -key cert.key -subj $subj
openssl x509 -req -in cert.req -out cert.cer -CAkey $ca_key -CA $ca_cer -days $expire_days -CAcreateserial
-CAserial serial
echo "${GREEN}Please distribute cert.cer freely"
echo "${RED}Please keep cert.key privately${NC}"
else
echo "Unknown operation: $operation"
help
fi
在nginx中使用證書
修改nginx配置文件 /etc/nginx/sites-available/xxxx
加入形如以下配置:
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /home/ethan/workspace/homesite/tools/cert.cer;
ssl_certificate_key /home/ethan/workspace/homesite/tools/cert.key;
分發(fā)CA根證書
分發(fā)安全
可以通過可靠的服務(如通過安全驗證的郵箱服務提供商、存儲下載提供商)將根證書發(fā)放給客戶端队丝。直接通過http鏈接發(fā)放給客戶端(如12306)的方式是不安全的蔫缸,僅限于實驗環(huán)境使用
Linux分發(fā)(SSH/Python的HTTPS訪問等)
瀏覽器中分發(fā)
Chrome:設置->高級設置->HTTPS/SSL "管理證書"
Firefox: Preferences->Advanced->View Certificates->Certificate Manager
iOS分發(fā)
待進一步研究
Android分發(fā)
待進一步研究