基於 OpenSSL 自建 CA 和頒發 SSL 證書
自建 CA 頒發證書不僅可以用來鑑權,而且使你的通訊更加的安全(請保護好你的證書)。在實際的軟體開發中,越來越多的服務用到 HTTPS,證書的需求隨之增加。那麼對於我們開發者,通過自簽名證書來進行測試必將非常的方便。so,有一個自己的 CA 是不是非常的庫呢!下面我們一步步操作,建立我們自己的 CA。
由於 Mac 自帶的 openssl 版本過低,請安裝更高版本。
建立 CA
所有命令均在同一目錄執行,沒有進行跳轉。
SH$ mkdir -p ./demoCA/{private,newcerts} && \
touch ./demoCA/index.txt && \
touch ./demoCA/serial && \
echo 01 > ./demoCA/serial
通過以上命令,你將得到如下目錄:
SH$ tree
.
└── demoCA
├── index.txt
├── newcerts
├── private
└── serial
生成 CA 根金鑰
$ openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048 #可以去掉des,以後簽證書不用輸密碼
生成 CA 證書請求
$ openssl req -new -days 3650 -key ./demoCA/private/cakey.pem -out careq.pem
自簽發 CA 根證書
$ openssl ca -selfsign -in careq.pem -out ./demoCA/cacert.pem -extensions v3_ca
以上合二為一
$ openssl req -new -x509 -days 3650 -key ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem -extensions v3_ca
到這裡,我們已經有了自己的 CA 了,下面我們開始為使用者頒發證書。
為使用者頒發證書
生成使用者 RSA 金鑰
$ openssl genrsa -des3 -out userkey.pem 2048 # 4096
生成使用者證書請求
SH$ openssl req -new -days 365 -key userkey.pem -out userreq.pem # NO SAN
$ openssl req -new -days 365 -key userkey.pem -out userreq.pem -config openssl.cnf #SAN
使用 CA 簽發證書
SH$ openssl ca -in userreq.pem -out usercert.pem # NO SAN
$ openssl ca -in userreq.pem -out usercert.pem -extensions v3_ca # 簽發中級 ca
$ openssl ca -in userreq.pem -out usercert.pem -config openssl.cnf -extensions v3_req #SAN
其他證書操作
- 檢視證書的內容:
$ openssl x509 -in cert.pem -text -noout
- 吊銷證書:
$ openssl ca -revoke cert.pem -config openssl.cnf
- 證書吊銷列表:
$ openssl ca -gencrl -out cacert.crl -config openssl.cnf
- 檢視列表內容:
$ openssl crl -in cacert.crl -text -noout
openssl.cnf
上面步驟中,你可以觀察到 SAN
與 NO SAN
標記。那麼什麼是 SAN
,SAN(Subject Alternative Name)是 SSL 標準 x509 中定義的一個擴充套件。使用了 SAN 欄位的 SSL 證書,可以擴充套件此證書支援的域名,使得一個證書可以支援多個不同域名的解析。所以,只執行 NO SAN
命令也可以簽發證書,不過卻不能夠新增多個域名。
想要新增多個域名或泛域名,你需要使用到該擴充套件。那麼預設的 OpenSSL 的配置是不能夠滿足的,我們需要複製或下載一份預設的 openssl.cnf 檔案到本地。如 github openssl。這裡我已經準備好一份 openssl.cnf。
修改匹配策略
預設匹配策略是:國家名,省份,組織名必須相同(match)。我們改為可選(optional),這樣避免我們生成證書請求檔案時(csr)去參考 CA 證書。
OPENSSL# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
修改預設值
這是可選項,修改預設值,可以讓你更快的頒發證書,一直回車就可以了:
OPENSSL[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Shanghai
localityName = Locality Name (eg, city)
localityName_default = Shanghai
0.organizationName = Organization Name (eg, company)
0.organizationName_default = deepzz
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = deepzz
關鍵步驟
最關鍵的地方是修改 v3_req
。新增成如下:
OPENSSL[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = abc.com
DNS.2 = *.abc.com
DNS.3 = xyz.com
IP.1 = 127.0.0.1
每次如果你要簽發不同域名或 IP,可以直接修改 [ alt_names ]
。
注意之後的操作,均要指定 -config openssl.cnf
。
再來看看我們的目錄結構:
SH$ tree
.
├── demoCA
│ ├── cacert.pem
│ ├── index.txt
│ ├── index.txt.attr
│ ├── index.txt.attr.old
│ ├── index.txt.old
│ ├── newcerts
│ │ └── 01.pem
│ ├── private
│ │ └── cakey.pem
│ ├── serial
│ └── serial.old
├── openssl.cnf
├── usercert.pem
├── userkey.pem
└── userreq.pem
環境變數
儘管很多文章都沒有說到,但 openssl 確實是支援環境變數的。
openssl 通過 $ENV::name
獲取環境變數,在配置檔案裡使用的時候只需將 name
替換為需要用到的環境變數的名稱就可以了。
其實上面的步驟可以改成這樣:
OPENSSL$ export SNAS=DNS:abc.com,DNS:*.abc.com,DNS:xyz.com,IP:127.0.0.1
# 修改 openssl.cnf
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = $ENV::SANS
# 註釋掉這段配置
#[ alt_names ]
#DNS.1 = abc.com
#DNS.2 = *.abc.com
#DNS.3 = xyz.com
#IP.1 = 127.0.0.1
參考連結
--EOF--
發表於 2017-05-21 16:03:00,並被新增「openssl、ca」標籤,最後修改於 2017-07-26 17:12:08。