很久以前介紹過使用 OpenSSL 建立 CA 並簽發 SSL 憑證, 相較於自我簽署憑證,客戶端可安裝自訂 CA 憑證避免程式因不信任自製憑證無法連線

但隨著時代演進,需求有點變化:

  1. HTTPS 已成資安基本要求,即使企業內部通訊也常被要求走 HTTPS,製作憑證的需求大增
  2. 2017 年 Chrome 58 / Firefox 48 開始要求憑證必須改用 SubjectAltName 欄位提供主機名稱 ,否則將顯示為不安全

第一點增加了需要製作憑證的頻率,每新增一台伺服器就需簽發一張憑證有點費事, 萬用字元憑證能讓我們省點力氣。 傳統憑證簽發對象只能指定特定網域名稱,例如:www.darkthread.net、api.darkthread.net。 而萬用字元憑證將適用對象擴大為特定網域下的任何網域名稱,例如:只要製作一張 *.darkthread.net 憑證, 即可安裝在 www.darkthread.net、blog.darkthread.net、api.darkthread.net、store.darkthread.net 等多個網站, 都視為有效。

第二點屬於憑證標準改變,導致過去做法製作的憑證,現在會被瀏覽器或客戶端視為不安全。

有鑑於此,2019 年版「使用 OpenSSL 製作萬用字元 SSL 憑證」食譜來了。

以下示範如何在 Windows 主機使用 OpenSSL 建立 CA 憑證並簽發萬用字元憑證。

  1. 第一步是要取得 OpenSSL。在 Windows 上過去需自行下載安裝,若為 Windows 10, 可考慮使用 Windows 上 Ubuntu 的 Bash, 但我最建議的做法是使用 Windows 工程師必備神器 Cmder 最省事, 下面也會以 Cmder 此示範。(還沒用過 Cmder 的同學可以試試,相信你也會愛上它的)
  2. 準備一個目錄放置產生的憑證,在此以 D:\SSL 示範
  3. 執行openssl genrsa -des3 -out rootCA.key 4096產生 rootCA.key,過程需設定密碼,稍後會用到
  4. 執行openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt 產生 CA 憑證 rootCA.crt
    題外話:days 參數為有效期限,之前遇過系統上線時隨手設了某個有效期限十年心想綽綽有餘,某天系統壞了,調查半天才驚覺程式已 默默跑了十年沒改版,這才悔恨自己看得不夠遠...
    所以,憑證有效期限怒抓 100 年(36500)好了 XD 這是玩笑話,依硬體能力增強的速度,資安防護相關機制估計撐不了多久就必須升級。
    建立憑證時要用到步驟 3. 設定密碼,接著要回答一串問題,若為內部使用,輸入內容不重要,程序完成後會得到 rootCA.crt。
  5. 這樣 CA 根憑證就做好了,應用時記得要安裝到客戶端。參考:憑證儲存區的選擇
  6. 接著要決定萬用字元憑證的域名,在這裡以 *.darkthread.net 為例
  7. 先產生萬用字元的憑證金鑰 openssl genrsa -out darkthread-net.key 2048
  8. 準備憑證要求的設定檔 darkthread-net.cnf 如下:
    [req]
    default_bits = 2048
    prompt = no
    default_md = sha256
    distinguished_name = dn
    
    [dn]
    C=TW
    ST=Taiwan
    L=Taipei
    O=Darkthread
    OU=Darkthread CA
    emailAddress=nobody@darkthread.net
    CN=*.darkthread.net
    
  9. 執行openssl req -new -sha256 -nodes -key darkthread-net.key -out darkthread-net.csr -config darkthread-net.cnf建立憑證請求darkthread-net.csr
  10. 準備 V3 設定檔 darkthread-net-v3.ext
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = *.darkthread.net
    
  11. 執行openssl x509 -req -in darkthread-net.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out darkthread-net.crt -days 36500 -sha256 -extfile darkthread-net-v3.ext,建立憑證 darkhread-net.crt,過程需要使用步驟 3 設定的密碼
  12. 要使用於 IIS,需將 .crt 轉為包含私鑰的 .pfx 格式,指令為openssl pkcs12 -export -out darkthread-net.pfx -inkey darkthread-net.key -in darkthread-net.crt -certfile rootCA.crt,執行後得到 darkthread-net.pfx,過程需要設定一組密碼,稍後在 IIS 安裝憑證時會用到。
  13. 開啟 IIS 管理介面,找到「伺服器憑證」,使用匯入功能匯入 darkthread-net.pfx

  14. 設定 HTTPS 繫結時就可以選取新做好的憑證
  15. 使用 Chrome 實測,完全符合安全要求,大功告成!

最後提醒一點,若想共用該 CA 憑證簽發其他伺服器憑證,記得妥善保存相關檔案及密碼。

Tutorial of wildcard certificate creation with OpenSSL on Windows and how to install it to IIS.


Comments

# by 無所不在

我執行到第4步驟 openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt 時出現錯誤: Can't open C:\Program Files (x86)\Common Files\SSL/openssl.cnf for reading, No such file or directory 2876:error:02001003:system library:fopen:No such process:crypto\bio\bss_file.c:69:fopen('C:\Program Files (x86)\Common Files\SSL/openssl.cnf','r') 2876:error:2006D080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:76:

# by Jeffrey

to 無所不在,你的 OpenSSL 是另外安裝的嗎?會不會你安裝的 OpenSSL 版本需要額外設定步驟?我建議改用 Cmder 試試,環境設定問題較少。

# by 無所不在

我的 OpenSSL 是去你提供的官網下載的 還是出錯, 看起來應該是[Common Files\SSL/openssl.cnf]中間的那個"/"在作怪,但我不知道要如何改? $ openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt Can't open C:\Program Files (x86)\Common Files\SSL/openssl.cnf for reading, No such file or directory 1948:error:02001003:system library:fopen:No such process:crypto\bio\bss_file.c:69:fopen('C:\Program Files (x86)\Common Files\SSL/openssl.cnf','r') 1948:error:2006D080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:76: Enter pass phrase for rootCA.key: unable to find 'distinguished_name' in config problems making Certificate Request 1948:error:0E06D06A:configuration file routines:NCONF_get_string:no conf or environment variable:crypto\conf\conf_lib.c:270:

# by Jeffrey

to 無所不在,https://stackoverflow.com/a/15416214/288936 試試加上 -config 參數。不過,我還是推薦用 Cmder 較省事。

# by 無所不在

我昨天就已經安裝 cmder,然後使用他來執行。 另外openssl 我下載的是 Win32OpenSSL-1_1_1d.msi。 可以了,謝謝。 等等有空再繼續往下研究。 參數改成如下: openssl req -config "c:\Program Files\OpenSSL-Win32\bin\openssl.cfg" -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt

# by perasa

請問 我執行到 8.準備憑證要求的設定檔 darkthread-net.cnf 如下: 請問cnf該如何產生呢? 是否是新增一個文字文件格式來修改成cnf檔呢? 謝謝

# by Jeffrey

to perasa, 用文字編輯器Notepad/Notepad++新開文字檔,參考第8點下方的文字範例修改貼入文字檔存成your-domain-name.cnf檔即可。

# by timhsiao

您好 我依照您的教學文件做到步驟11.出現下列錯誤,請問可能是那邊做錯造成的呢? Error Loading extension section default 12188:error:2206E068:X509 V3 routines:X509V3_get_value_bool:invalid boolean string:crypto\x509v3\v3_utl.c:263:section:<NULL>,name:CA,value:FALES 12188:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto\x509v3\v3_conf.c:47:name=basicConstraints, value=CA:FALES

# by Jeffrey

to timhsiao, basicConstraints=CA:FALSE <= 是不是誤打成 CA:FAL**ES**?

# by timhsiao

to Jeffrey, 感謝您的幫助真的是我手誤打錯,看半天沒看出來,謝謝您的幫忙。

Post a comment


60 + 36 =