From: 011netservice@gmail.com Date: 2022-04-24 Subject: SSL20220226.txt 歡迎來信交流. □,○,△,▽,☆,◇,✓,✗, ---------- 20220226 建立萬用字元憑證 參考: https://blog.darkthread.net/blog/issue-wildcard-ssl-cert-with-openssl/ 使用 OpenSSL 建立 CA 並簽發 SSL 憑證, 相較於自我簽署憑證,客戶端可安裝自訂 CA 憑證避免程式因不信任自製憑證無法連線。 2017 年瀏覽器開始要求憑證必須改用 SubjectAltName 欄位提供主機名稱. 例如: www.011.idv.tw, svc.011.idv.tw. 萬用字元憑證將適用對象擴大為特定網域下的任何網域名稱,例如:只要製作一張 *.011.idv.tw 憑證, 就可以在 011.idv.tw 網域中視為有效. 以下測試, 以 *.011.idv.tw, domainCA, 011idvtw 為 keywords: □ OpenSSL Win64OpenSSL-1_1_1m.msi (先安裝這個) Win64OpenSSL-3_0_1.msi (再安裝這個, 兩個都要安裝) 安裝目錄為 C:\Program Files\OpenSSL-Win64. C:\Program Files (x86)\OpenSSL-Win32 為 32位元安裝目錄. 執行時需先安裝 Visual C++ 2008 Redistributables. X64版本 以系統管理員開啟PowerShell, 切換到目錄 C:\Program Files\OpenSSL-Win64\bin □ 建立 CA 憑證 ○ 建立(CA私鑰 domainCA.key) 建立 CA 私鑰檔案 (RSA Private/public keys), domainCA.key 密碼 = password20220226 後面會繼續用到, 輸入過程看不到, 需重複驗證. PS C:\Program Files\OpenSSL-Win64\bin> .\openssl genrsa -des3 -out domainCA.key 4096 Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ○ 建立(CA公鑰 domainCA.crt) 建立 (CA 公鑰檔案, domainCA.crt 憑證). 參數說明: -config, 指定 openssl.cfg 檔案位置. -days, 有效日數 8000 日約 20年以上. -key, 指定 domainCA.key (RSA Private/public keys) -out, 要產生的 CA 憑證 domainCA.crt openssl.cfg 中預設憑證要求檔所輸入的國家、州省、組織名稱必須與CA一致,此點可修改openssl.cfg的[ policy_match ]設定放寬 PS C:\Program Files\OpenSSL-Win64\bin> .\openssl req -config "C:\Program Files\OpenSSL-Win64\bin\openssl.cfg" -x509 -new -nodes -key domainCA.key -sha256 -days 8000 -out domainCA.crt Enter pass phrase for domainCA.key: <-- 輸入前面的密碼 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) [AU]:TW <-- 輸入國家 State or Province Name (full name) [Some-State]:Taiwan <-- 輸入州省 Locality Name (eg, city) []:Taipei <-- 輸入 Organization Name (eg, company) [Internet Widgits Pty Ltd]:011idvtw <-- 輸入組織名稱 Organizational Unit Name (eg, section) []:011idvtw CA <-- 輸入 Common Name (e.g. server FQDN or YOUR name) []:011idvtw CA <-- 改成case2輸入, 待確認何者才正確? 本次測試使用這個! Email Address []:someoneCA@mail.com <-- 輸入 以上 case2: 本次測試使用這個! Common Name (e.g. server FQDN or YOUR name) []:011idvtw CA <-- 改成case2輸入, 待確認何者才正確? 本次測試使用這個! 執行結果在目錄: CodeHelper\Certificate\OpenSSL\SSL20220227\case2-NameIsSameAsCA case1: 照以前測試方式輸入 Common Name (e.g. server FQDN or YOUR name) []:*.011.idv.tw <-- case1=照以前測試方式輸入 執行結果在目錄: CodeHelper\Certificate\OpenSSL\SSL20220227\case1-RootCAShouldHaveSameNameAsCert 若用 Windows SSL Certificate cleaner 檢查, 提示錯誤為 Root CA should have same name as Cert. (CA 公鑰檔案, domainCA.crt 憑證) 要安裝到客戶端電腦. □ 建立 萬用字元 SSL 憑證 ○ 建立(網站私鑰 011IdvTw.key). .\openssl genrsa -out 011idvtw.key 2048 ○ 建立(憑證請求檔案 011idvtw.csr). △ 先建立(網站基本資料 011idvtw.cnf 檔案, 網站基本資料內容應跟(CA公鑰 domainCA.crt)相同, 編輯內容如下: [req] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = 011idvtw [011idvtw] C=TW ST=Taiwan L=Taipei O=011idvtw OU=011idvtw CA emailAddress=someone@011.idv.tw CN=*.011.idv.tw △ 再建立(憑證請求檔案 011idvtw.csr). .\openssl req -new -sha256 -nodes -key 011idvtw.key -out 011idvtw.csr -config 011idvtw.cnf ○ 建立 萬用字元 SSL 憑證 011idvtw.crt △ 先建立 011idvtw-v3.ext 檔案, 編輯內容如下: authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = *.011.idv.tw △ 再建立 萬用字元 SSL 憑證檔案 011idvtw.crt .\openssl x509 -req -in 011idvtw.csr -CA domainCA.crt -CAkey domainCA.key -CAcreateserial -out 011idvtw.crt -days 8000 -sha256 -extfile 011idvtw-v3.ext 執行過程, 要輸入前面的密碼後, 產生憑證檔案 011idvtw.crt □ IIS ○ 建立 011idvtw.pfx IIS 不能使用 .crt 檔案, 必需將 .crt 檔案轉為 包含私鑰的 .pfx 檔案. 建立 .pfx 時, 會要求設定 .pfx 檔案密碼. .\openssl pkcs12 -export -out 011idvtw.pfx -inkey 011idvtw.key -in 011idvtw.crt -certfile domainCA.crt 將(私鑰 011idvtw.key + 公鑰 011idvtw.crt + 公鑰 domainCA.crt) export 為 011idvtw.pfx. 測試密碼為: pfx20220226, 注意不要使用於正式環境. ○ 在 IIS 管理介面,找到「伺服器憑證」,使用匯入功能匯入 011idvtw.pfx, 到憑證儲存區=個人 ○ 設定 HTTPS 繫結時就可以選取新做好的憑證 以上共 8 個檔案. □ 手動匯入客戶端電腦(受信任的根憑證授權單位) 將伺服器電腦上 ○ 本機電腦.受信任的根憑證授權單位.憑證.(*.011.idv.tw).匯出公鑰為 011idvtw.cer. ○ 本機電腦.受信任的發行者.憑證.011idvtw CA.匯出公鑰為 domainCA.cer. 在客戶端電腦上 ○ 本機電腦.受信任的根憑證授權單位.憑證.(*.011.idv.tw).匯入公鑰為 011idvtw.cer. todo: 待查出指令模式, 可由程式直接匯入. 匯入後, TCP/IP 可使用 SSL 加密通訊協定, ○ 伺服器電腦上, 可通過 TcpListener.??? ○ 客戶端電腦上, 可通過 TcpClient.??? ---------- 20220225 使用 OpenSSL 製作萬用字元 SSL 憑證, 2019-01-21 https://blog.darkthread.net/blog/issue-wildcard-ssl-cert-with-openssl/ 很久以前介紹過使用 OpenSSL 建立 CA 並簽發 SSL 憑證, 相較於自我簽署憑證, 客戶端可安裝自訂 CA 憑證避免程式因不信任自製憑證無法連線。 但隨著時代演進,需求有點變化: HTTPS 已成資安基本要求,即使企業內部通訊也常被要求走 HTTPS,製作憑證的需求大增 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. 產生 rootCA.key (RSA Private/public keys) 執行openssl genrsa -des3 -out rootCA.key 4096產生 rootCA.key,過程需設定密碼,稍後會用到 20200123, test ok openssl genrsa -des3 -out rootCA.key 4096 密碼= password20200123 4. 產生 CA 憑證 rootCA.crt 執行openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt 產生 CA 憑證 rootCA.crt 20200123, test: openssl req -config "c:\Program Files\OpenSSL-Win32\bin\openssl.cfg" -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt 改成這樣才OK: openssl req -config "C:\Program Files (x86)\OpenSSL-Win32\bin\openssl.cfg" -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt 參數說明: -config 指定 openssl.cfg 檔案位置 -days 有效日數 -key 指定 rootCA.key (RSA Private/public keys) -out 要產生的 CA 憑證 rootCA.crt 執行後先要求輸入輸入密碼= password20200123 <--- 這是測試密碼, 別再用於正式環境! 執行過程: D:\SSL λ openssl req -config "C:\Program Files (x86)\OpenSSL-Win32\bin\openssl.cfg" -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt WARNING: can't open config file: /usr/local/ssl/openssl.cnf Enter pass phrase for rootCA.key: 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) [AU]:Taiwan string is too long, it needs to be less than 2 bytes long Country Name (2 letter code) [AU]:TW <---- State or Province Name (full name) [Some-State]:Taiwan <---- Locality Name (eg, city) []:Taipei <---- Organization Name (eg, company) [Internet Widgits Pty Ltd]:011IdvTw <---- Organizational Unit Name (eg, section) []:011IdvTw CA <---- Common Name (e.g. server FQDN or YOUR name) []:*.011.idv.tw <---- Email Address []:011netservice@gmail.com <---- 題外話:days 參數為有效期限,之前遇過系統上線時隨手設了某個有效期限十年心想綽綽有餘, 某天系統壞了,調查半天才驚覺程式已 默默跑了十年沒改版,這才悔恨自己看得不夠遠... 所以,憑證有效期限怒抓 100 年(36500)好了 XD 這是玩笑話,依硬體能力增強的速度,資安防護相關機制估計撐不了多久就必須升級。 建立憑證時要用到前面步驟設定密碼,接著要回答一串問題,若為內部使用,輸入內容不重要,程序完成後會得到 rootCA.crt。 5. 這樣 CA 根憑證就做好了,應用時記得要安裝到客戶端。參考:憑證儲存區的選擇 6. 接著要決定萬用字元憑證的域名,在這裡以 *.darkthread.net 為例 7. 先產生萬用字元的憑證金鑰 openssl genrsa -out darkthread-net.key 2048 產生萬用字元的憑證金鑰指令改成 openssl genrsa -out 011IdvTw.key 2048, 執行結果: λ openssl genrsa -out 011IdvTw.key 2048 WARNING: can't open config file: /usr/local/ssl/openssl.cnf Generating RSA private key, 2048 bit long modulus .......................+++ ............................+++ e is 65537 (0x10001) 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 改為如下檔案名稱: 011IdvTw.cnf, 內容為: [req] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = 011IdvTw [011IdvTw] C=TW ST=Taiwan L=Taipei O=011IdvTw OU=011IdvTw CA emailAddress=011netservice@gmail.com CN=*.011.idv.tw 9. 執行 openssl req -new -sha256 -nodes -key darkthread-net.key -out darkthread-net.csr -config darkthread-net.cnf 建立憑證請求 darkthread-net.csr 建立憑證請求檔案 指令改成: openssl req -new -sha256 -nodes -key 011IdvTw.key -out 011IdvTw.csr -config 011IdvTw.cnf 可得出憑證請求檔案 = 011IdvTw.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 檔名改成: 011IdvTw-v3.ext 內容改成: authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = *.011.idv.tw 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 設定的密碼 指令改成執行 openssl x509 -req -in 011IdvTw.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out 011IdvTw.crt -days 36500 -sha256 -extfile 011IdvTw-v3.ext 會要求輸入前面的密碼後, 產生 011IdvTw.crt 憑證 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 安裝憑證時會用到。 指令改成執行 openssl pkcs12 -export -out 011IdvTw.pfx -inkey 011IdvTw.key -in 011IdvTw.crt -certfile rootCA.crt 設定密碼為 passpfx <--- 這是測試密碼, 別再用於正式環境! 13. 開啟 IIS 管理介面,找到「伺服器憑證」,使用匯入功能匯入 darkthread-net.pfx 改成匯入 011IdvTw.pfx 選取憑證儲存區=個人 14. 設定 HTTPS 繫結時就可以選取新做好的憑證 15. 使用 Chrome 實測,完全符合安全要求,大功告成! 最後提醒一點,若想共用該 CA 憑證簽發其他伺服器憑證,記得妥善保存相關檔案及密碼。