From: 011netservice@gmail.com Date: 2023-01-01 Subject: readme-Certificate.txt path: CodeHelper\Certificate\readme-Certificate.txt 歡迎來信交流, 訂購軟體需求. □ 憑證檔案副檔名: 詳段落( □ 建立憑證: 開發專用的自我簽核憑證 makecert -sky exchange -r -n "CN=localhost" -pe -a sha256 -len 2048 -ss root -sr CurrentUser -sk 20211128 makecert -sky exchange -r -n "CN=localhost" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk 20211128 makecert -sky exchange -r -n "CN=localhost" -pe -a sha256 -len 2048 -ss root -sr CurrentUser -sk 20211128 -b 01/01/2021 -e 01/01/2100 makecert -sky exchange -r -n "CN=localhost" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk 20211128 -b 01/01/2021 -e 01/01/2100 makecert -sky exchange -r -n "CN=certificate1" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk 20211128 -b 01/01/2021 -e 01/01/2100 makecert.exe | 例如 Windows 11 在 C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64 下. Windows 10 在 C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x64 C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64, 20220129 這種憑證, 無法通過...todo...檢驗. 只能用在 Server host=localhost. 當跨主機IP, 或是127.0.0.1時, 就無法通過. 取巧: 127.0.0.1 的 IP 可以自行用 localhost 對應通過. to test: 利用取巧方法, 自行對應 60.250.98.234 = www.011.idv.tw □ 憑證管理: ○ Windows 憑證管理程式有2個啟動程式 △ certlm [憑證 - 本機電腦], △ certmgr [憑證 - 目前的使用者] ○ 有效的存放位置: △ certlm - [憑證 - 本機電腦\個人\憑證] △ certlm - [憑證 - 本機電腦\受信任的根憑證授權單位\憑證] <-- 放到這裡就對了, 全機都可用! △ certmgr - [憑證 - 目前的使用者\個人\憑證] △ certmgr - [憑證 - 目前的使用者\受信任的根憑證授權單位\憑證] ○ 身分區分為3種, 只能看到屬於自己身分存放的憑證. △ My user account △ Service account △ Computer account 以下 #### 標記段落, **** 標記常用. 項目符號: □,○,△,◇, ■,●,▲,◆, ✓, ✔, ✗, ✘, ☐, ☑, ☒. ---------- 2022-12-11 #### 憑證檔案格式. 憑證檔案格式 crt, cer, cert 都是 Certificate 的縮寫. □ 跨平台共通標準 編碼格式 ○ .der, Distinguished Encoding Rules. △ 2進位格式 △ 常見副檔名為 ◇ .der, ◇ .cer, 常用於 Windows. ◇ .crt, 格式不一定, 建議少用. ○ .pem, Privacy Enhanced Mail. △ base64 文字格式, 內容是 DER 檔案經由 Base64 編碼後的字串. △ 以 -----BEGIN ***----- 開頭,以 -----END ***----- 結尾 △ 常見副檔名為 ◇ .pem ◇ .cert, 常用於 Linux. ◇ .crt, 格式不一定, 建議少用. .pem stands for PEM, Privacy Enhanced Mail; it simply indicates a base64 encoding with header and footer lines. Mail traditionally only handles text, not binary which most cryptographic data is, so some kind of encoding is required to make the contents part of a mail message itself (rather than an encoded attachment). The contents of the PEM are detailed in the header and footer line - .pem itself doesn't specify a data type - just like .xml and .html do not specify the contents of a file, they just specify a specific encoding; □ .csr or .req, Certificate Signing Request as defined in PKC #10 憑證請求檔 內含 CA (Certificate Authority) 應包含的 public key, common name...等資訊. .csr or .req or sometimes .p10 stands for Certificate Signing Request as defined in PKCS#10; it contains information such as the public key and common name required by a Certificate Authority to create and sign a certificate for the requester, the encoding could be PEM or DER (which is a binary encoding of an ASN.1 specified structure); □ .crt or .cer, Certificate 公鑰或憑證 內含 public key, ...等已由 CA (Certificate Authority)簽證的重要資訊. 可能為 (DER encoded binary X.509) 或 (Base-64 encoded X.509) 編碼. .crt or .cer stands simply for certificate, usually an X509v3 certificate, again the encoding could be PEM or DER; a certificate contains the public key, but it contains much more information (most importantly the signature by the Certificate Authority over the data and public key, of course). △ base64 文字格式, 內容是 DER 檔案經由 Base64 編碼後的字串. □ .key ○ 存私鑰或公鑰, 通常是私鑰. ○ 可能是 PEM 或 DER 編碼格式, 通常是 PEM 格式. Linux 常用. ○ 不一定加密過. .key can be any kind of key, but usually it is the private key - OpenSSL can wrap private keys for all algorithms (RSA, DSA, EC) in a generic and standard PKCS#8 structure, but it also supports a separate 'legacy' structure for each algorithm, and both are still widely used even though the documentation has marked PKCS#8 as superior for almost 20 years; both can be stored as DER (binary) or PEM encoded, and both PEM and PKCS#8 DER can protect the key with password-based encryption or be left unencrypted; □ .pfx, 個人資訊交換-PKCS #12(.PFX,.P12), Personal Information Exchange, 檔案內含一組密碼. 包含(私鑰及公鑰), IIS 網站繫結時使用. □ .P7B, 密碼編譯訊息語法標準 - PKCS #7 憑證 (.P7B), Cryptographic Message Syntax Standard - PKC #7 Certificates. □ .SST, Microsoft 序列憑證存放區, Microsoft Serialized Certificate Store ref: https://crypto.stackexchange.com/questions/43697/what-are-the-differences-between-pem-csr-key-crt-and-other-such-file-exte 其餘編碼格式可參考: https://blog.miniasp.com/post/2018/04/21/PKI-Digital-Certificate-Format-Convertion-Notes 以下舊紀錄, 確認後移到上方: ○ .key, 私鑰或金鑰, 包含(私鑰及公鑰), 使用 PEM 格式, 無密碼保護. ○ .crt, 公鑰或憑證, (使用 PEM 格式) ○ .pfx, 個人資訊交換-PKCS #12(.PFX,.P12), Personal Information Exchange, 檔案內含一組密碼. 包含(私鑰及公鑰), IIS 網站繫結時使用. ○ .cer, 公鑰, 可再細分為 (DER encoded binary X.509) 或 (Base-64 encoded X.509 文字檔). ○ .csr, 公鑰, 憑證請求檔案, 搭配(.cnf檔案包含網站基本資料), 交付至(第三方 CA 認證單位), 申請建立(網站憑證.crt檔案). ○ .P7B, 密碼編譯訊息語法標準 - PKCS #7 憑證 (.P7B), Cryptographic Message Syntax Standard - PKC #7 Certificates. ○ .SST, Microsoft 序列憑證存放區, Microsoft Serialized Certificate Store ---------- 2022-08-14, #### SSL—HTTPS 背後功臣. https://codecharms.me/posts/security-ssl-https 上一篇講到 SSH (Secure Shell),一種加密連線方式,確保我們對遠端伺服器發送指令時,能夠不被竊聽或是竄改命令。 本篇一鼓作氣,來介紹與 SSH (縮寫)只有一字之差的 SSL–Secure Sockets Layer。它們不僅名字相似,功能/目的也滿接近的。對了,這是 Security 資訊安全系列文第三篇! 本篇文章會從 SSL 基礎概念談起,介紹 SSL 背後原理、相關名詞介紹(包含 TLS, CA, chain of trust, OpenSSL)、 OpenSSL 實際操作、與 SSL 憑證種類。開始吧! SSL: Secure Sockets Layer 當我們瀏覽網頁時,我們都有個好習慣:先檢查網址列的開頭是不是有個 🔒鎖的圖案。 這個鎖代表什麼?代表你現在連線到的網站是安全可信任的。更準確的說,這個鎖的記號代表你與這個網站是使用安全的 HTTPS (HTTP Secure) 連線,而不是使用不安全的 HTTP protocol。連線後,只有瀏覽器本人跟網站能夠解讀雙方之間傳遞的資料,就算其他人想要從中攔截(比如說你的使用者帳號密碼),也沒辦法。 HTTPS 背後的 protocol,就是 SSL。 SSL 加密步驟 SSL 讓瀏覽器(所謂的 client)要連到一個遠端網站(所謂的 server)之前,先要求這個網站提供身分認證,跟這個網站約定暗號(交換鑰匙),打好交情(建立加密的 session),才會心甘情願地跟這個網站連線。可以分成六個步驟: 瀏覽器對想要連線的網站送出連線請求,同時要求網站驗證自己。 網站將自己的 SSL 數位憑證 (SSL certificate) 回傳給 client,裡面包含了網站的 public key。 瀏覽器驗證網站回傳的的 root certificate,透過 chain of trust 機制 確認這個證明文件是否可以被信認,同時也確認這個憑證是否過期。 當認證通過,瀏覽器會用網站的 public key 建立一個 symmetric session key。 網站用自己的 private key 解讀 session key,並且回傳一個確認訊息,開始一個被 SSL 保護的 session。 這個 session key 會被用來加密所有之後瀏覽器與網站之間傳送的資料。 下面來介紹一些 SSL 相關名詞。 TLS: Transport Layer Security Protocol 在上一篇文中有稍微提到 TLS 的歷史,簡而言之,由於 SSL 已經不再安全(POODLE 與 DROWN 是兩個曾經發生過的著名攻擊),所以現在已經被 TLS protocol 取代。慣性使然,當我們說 SSL(比如說 SSL 憑證)時,大部分情況其實是在說 TLS。 CA: Certificate Authority 數位憑證認證機構,簡稱 CA,是負責發放與管理數位憑證 (certificate)的單位。前面提到進行 SSL 連線的前置作業是 server 要提供數位憑證讓瀏覽器驗證,但瀏覽器要怎麼驗證?它會去看這個憑證是不是被一個它相信的 CA 簽署的。如果是,那瀏覽器就相信這個 server 可以信任,如果不是,那瀏覽器就再看這個 CA 有沒有它自己的 certificate,如果有,而這個 certificate 是被一個瀏覽器信任的 CA 簽的,那就放行,如果沒有,就再往下找。如果一路找下去,找不到可以信任的 CA,就失敗。 假設今天世界上有甲乙丙三家 CA。CA 丙簽了 CA 乙的憑證,而 CA 乙簽了 CA 甲的憑證。瀏覽器小明想連線到網站 A,而小明只知道 CA 丙。連線前,網站 A 傳了它的 certificate 們給小明。小明先看第一張,眉頭一皺,發現 A 的憑證是不認識的 CA 甲簽的,往下翻,看到 CA 乙簽了甲的憑證,但小明也不認識乙,所以繼續往下翻,下一張是乙的憑證,是 CA 丙簽署的—bingo! 於是網站 A 順利與小明建立連線。 所以 CA 其實很像保證人的角色,它向瀏覽器保證一個網域的合法性,讓想要連線的那一方確保自己的連線對象是安全的。 Chain of Trust 這樣一層一層檢查 certificate,直到找到信任的 CA 的機制,叫做 chain of trust。你可能會疑惑,為什麼不直接讓所有 server 都帶著 CA 丙簽的 certificate 就好了?為什麼還需要經過這麼多層?主要原因是安全。如果今天壞人 B 找到一個破解 CA 甲的方法,可以偽造甲的簽名,這個漏洞一旦被發現,所有被甲簽過的憑證就都沒有意義了,那些網域必須要重新找 CA 來擔保自己的合法性。 使用 chain of trust 的好處是,它可以降低 root CA(chain of trust 的源頭 CA,就是例子中的 CA 丙)被暴露的風險。不過這也代表,要成為一個 root CA,安全防護必須要做到謹慎再謹慎,不然如果 root CA 的私鑰被攻破了,後果不堪設想。 OpenSSL SSL/TLS 是 protocol,而 OpenSSL 就是一個開源的實作(SSH 與 OpenSSH 也是同樣的關係)。 捲起袖子玩一玩 如果你的電腦是 Unix 系列的,很大的機率是系統已經裝好 OpenSSL 了。如果是 Windows 系統,也可以直接去網站下載最新的版本。 $openssl version LibreSSL 2.6.5 可以先打開終端機,試試 version 指令,如果有回傳版本給你,就代表你的電腦已經有 OpenSSL 了。 用 $openssl help(或是任何 OpenSSL 不認得的指令...)就可以看到 OpenSSL 提供的指令包。 其中 s_client 是一個挺實用的工具,讓我們診斷與測試 SSL 的安全連線。下面示範測試 jennycodes.me 網站的 SSL 狀態。 $openssl s_client -connect jennycodes.me:443 -servername jennycodes.me CONNECTED(00000005) depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root verify return:1 depth=1 C = US, ST = CA, L = San Francisco, O = "CloudFlare, Inc.", CN = CloudFlare Inc ECC CA-2 verify return:1 depth=0 C = US, ST = CA, L = San Francisco, O = "CloudFlare, Inc.", CN = sni.cloudflaressl.com verify return:1 --- Certificate chain 0 s:/C=US/ST=CA/L=San Francisco/O=CloudFlare, Inc./CN=sni.cloudflaressl.com i:/C=US/ST=CA/L=San Francisco/O=CloudFlare, Inc./CN=CloudFlare Inc ECC CA-2 1 s:/C=US/ST=CA/L=San Francisco/O=CloudFlare, Inc./CN=CloudFlare Inc ECC CA-2 i:/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root --- Server certificate -----BEGIN CERTIFICATE----- (略) -----END CERTIFICATE----- subject=/C=US/ST=CA/L=San Francisco/O=CloudFlare, Inc./CN=sni.cloudflaressl.com issuer=/C=US/ST=CA/L=San Francisco/O=CloudFlare, Inc./CN=CloudFlare Inc ECC CA-2 --- No client certificate CA names sent Server Temp Key: ECDH, X25519, 253 bits --- SSL handshake has read 2642 bytes and written 307 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-CHACHA20-POLY1305 Server public key is 256 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-ECDSA-CHACHA20-POLY1305 Session-ID: 5FEF2BA2A72483061BEB18C92222BBC507A1A95749AE67094F2863D537B7C600 (略) Verify return code: 0 (ok) --- closed 結果長這樣。解釋一下,我目前用的 SSL 是直接從 CloudFlare (CDN 伺服器)設定,不影響效用,但是 certificate 不會看到 jennycodes.me 的字樣。從上面一路看下來,certificate chain 的部分可以看到 openssl client 經過兩步 chain of trust 就認證了 jennycodes.me 網域(CloudFlare Inc ECC CA-2 -> Baltimore CyberTrust Root),緊接著的是 server certificate 內容,再下面可以注意的是 SSL-Session 下的 protocol 是用 TLSv1.2,而不是 SSL。 如果加上 -state 指令,變成: $openssl s_client -connect jennycodes.me:443 -servername jennycodes.me -state 就會看到前面出現這段 SSL_connect:before/connect initialization SSL_connect:SSLv3 write client hello A SSL_connect:SSLv3 read server hello A depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root verify return:1 depth=1 C = US, ST = CA, L = San Francisco, O = "CloudFlare, Inc.", CN = CloudFlare Inc ECC CA-2 verify return:1 depth=0 C = US, ST = CA, L = San Francisco, O = "CloudFlare, Inc.", CN = sni.cloudflaressl.com verify return:1 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server key exchange A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read server session ticket A SSL_connect:SSLv3 read finished A 可以看到連線前的握手過程,逐步確認 SSL 連線的步驟是否正確,滿好玩的。 再來,上面的指令只會顯示最前面那張 certificate 內容(也就是 server certificate)。如果想要看到所有的 certificate ,可以加上 -showcerts: $openssl s_client -connect jennycodes.me:443 -servername jennycodes.me -showcerts 就可以拿到包含 root certificate 的所有憑證了。 光是 s_client 就有很多指令可以用了,這邊送上 s_client 的 man page,請好奇的人自行欣賞。 SSL 憑證種類 依照安全層級(validation level)分類的話,SSL 憑證可以分成三種:Domain Validated (DV), Organization Validated (OV), Extended Validation (EV)。以下分別介紹: Domain Validated SSL Certificates (DV) SSL 中安全層級:低 費用:低 CA 認證時,單純確認這個組織是否真的擁有這個網域(通常使用 email 確認)。 從上面的那三張 certificate 名稱中就已經可以看到該組織用的是哪一種 SSL certificate 了。拿 PicCollage 當例子,中間的那張 Sectigo RSA Domain Validation Secure Server CA 代表 PicCollage 使用的是 DV certificate。下面的 Details 欄位也可以看到 subject 就只有單純顯示 common name 這個資訊。 Organization Validated SSL Certificates (OV) SSL 中安全層級:中 費用:中 CA 除了確認該組織是否擁有這個網域之外,也會聯絡並稍微調查該組織,確認該組織是可信的。發放的憑證中會有該組織的相關資訊,像是名字與位置。 跟 DV 比起來,OV 可以看到的訊息就更多,像是地區與組織名稱。 Extended Validation SSL Certificates SSL 中安全層級:高 費用:高 CA 除了該組織的網域所有權、組織基本資料、實體位置,還會驗證該組織的法律地位。這種證書需要組織提供文件與耐心 (?) 來等待審核通過。 EV 比起 OV 又多了一些資訊,像是 business category 與 serial number。同樣可以從上面的 certificate issuer 看到這是 EV 等級的 SSL 憑證。 若是依照網域/子網域數(number of secured domains/subdomains)分類,則 SSL 憑證也可以分成Wildcard, Multi-Domain (MDC), Unified Communications (UCC) 三種。這邊比較直觀,就不細講啦。 後話 最近我們的 Android team 遇到一個問題:有兩台 Samsung 的測試手機不知道為什麼一直無法連到 PicCollage 伺服器拿資料,錯誤訊息顯示是因為 SSL 無法認證。有趣的是只有這兩台 Samsung 手機出事,如果是 SSL 憑證的問題應該是所有手機都會被影響。我們試了一些不同方法,後來參考這裡跟這裡將 server certificate 掛在 Android 程式碼中,直接承認這張 certificate 的合法性。可以動了,卻不是根本性的解法。 後來,找到了原因:這兩台 Samsung 裝置的系統時間被改過了(改到了很久以後的未來),而我們的 SSL 最近剛要過期,所以系統認為我們的 SSL 憑證早就已經過期了... 也是因為如此,這篇文章才會這麼早出現(本來想先寫其他更有趣的主題)(SSL 對不起),為了追這個 bug,順手查了一些相關資料,想想其實乾脆再順手一點,就把 SSL 寫出來了。 ---------- 2022-08-10, #### 查看憑證申請紀錄. https://crt.sh/?q=YOUR-DOMAIN.com It's a web interface. that lets you search for certs that have been logged by CT. https://crt.sh. Pronounced "search". Criteria Type: Identity Match: ILIKE Search: 'www.chinatimes.com' Certificates crt.sh ID Logged At ⇧ Not Before Not After Common Name Matching Identities Issuer Name 631035680 2018-08-05 2018-07-26 2019-10-25 chinatimes.com www.chinatimes.com C=US, O=DigiCert Inc, OU=www.digicert.com, CN=GeoTrust RSA CA 2018 613078230 2018-07-26 2018-07-26 2019-10-25 chinatimes.com www.chinatimes.com C=US, O=DigiCert Inc, OU=www.digicert.com, CN=GeoTrust RSA CA 2018 321581550 2018-02-03 2015-05-17 2016-05-18 chinatimes.com www.chinatimes.com C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G4 320240380 2018-02-03 2016-04-26 2017-06-25 chinatimes.com www.chinatimes.com C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3 308091427 2018-01-19 2017-05-02 2018-08-01 chinatimes.com www.chinatimes.com C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3 131779995 2017-05-02 2017-05-02 2018-08-01 chinatimes.com www.chinatimes.com C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3 17346037 2016-04-26 2016-04-26 2017-06-25 chinatimes.com www.chinatimes.com C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3 https://crt.sh/?q=*.011.idv.tw <--- OK, 申請前 Criteria Type: Identity Match: ILIKE Search: '*.011.idv.tw' Certificates crt.sh ID Logged At ⇧ Not Before Not After Common Name Matching Identities Issuer Name 6824610959 2022-05-29 2022-05-29 2022-08-27 *.011.idv.tw *.011.idv.tw C=US, O=Let's Encrypt, CN=R3 6824612101 2022-05-29 2022-05-29 2022-08-27 *.011.idv.tw *.011.idv.tw C=US, O=Let's Encrypt, CN=R3 https://crt.sh/?q=*.011.idv.tw <--- OK, 申請後 Criteria Type: Identity Match: ILIKE Search: '*.011.idv.tw' Certificates crt.sh ID Logged At ⇧ Not Before Not After Common Name Matching Identities Issuer Name 7309113971 2022-08-10 2022-08-10 2022-11-08 *.011.idv.tw *.011.idv.tw C=US, O=Let's Encrypt, CN=R3 7309114808 2022-08-10 2022-08-10 2022-11-08 *.011.idv.tw *.011.idv.tw C=US, O=Let's Encrypt, CN=R3 6824610959 2022-05-29 2022-05-29 2022-08-27 *.011.idv.tw *.011.idv.tw C=US, O=Let's Encrypt, CN=R3 6824612101 2022-05-29 2022-05-29 2022-08-27 *.011.idv.tw *.011.idv.tw C=US, O=Let's Encrypt, CN=R3 https://crt.sh/?q=main.011.idv.tw <--- OK Criteria Type: Identity Match: ILIKE Search: 'main.011.idv.tw' Certificates crt.sh ID Logged At ⇧ Not Before Not After Common Name Matching Identities Issuer Name 7184619068 2022-07-23 2022-07-23 2022-10-21 main.011.idv.tw main.011.idv.tw C=US, O=Let's Encrypt, CN=R3 7183270752 2022-07-23 2022-07-23 2022-10-21 main.011.idv.tw main.011.idv.tw C=US, O=Let's Encrypt, CN=R3 6726634084 2022-05-14 2022-05-14 2022-08-12 main.011.idv.tw main.011.idv.tw C=US, O=Let's Encrypt, CN=R3 6726837916 2022-05-14 2022-05-14 2022-08-12 main.011.idv.tw main.011.idv.tw C=US, O=Let's Encrypt, CN=R3 https://crt.sh/?q=011.idv.tw <--- 502 Bad Gateway ---------- #### IIS 網站匯入並繫結憑證 請以 CodeHelper\Windows\IIS\readme-iis.txt 為準 ---------- #### 設定 IIS 網站瀏覽 http 時自動轉成為 https. 請以 CodeHelper\Windows\IIS\readme-iis.txt 為準 ---------- 2022-05-15, ####OpenSSL ref: CodeHelper\Certificate\OpenSSL\readme-OpenSSL.txt. ---------- 2022-05-15, ####Let's Encrypt ref: CodeHelper\Certificate\LetsEncrypt\readme-LetsEncrypt.txt ---------- 2022-05-15, ####以下舊紀錄待確認後放到上面. ---------- 2022-05-02, 常用: 使用 OpenSSL 製作萬用字元 SSL 憑證: ○ OpenSSL for Windows: http://slproweb.com/products/Win32OpenSSL.html The Win32/Win64 OpenSSL Installation Project is dedicated to providing a simple installation of OpenSSL for Microsoft Windows. It is easy to set up and easy to use through the simple, effective installer. No need to compile anything or jump through any hoops, just click a few times and it is installed, leaving you to doing real work. Download it today! Note that these are default builds of OpenSSL and subject to local and state laws. More information can be found in the legal agreement of the installation. 執行時需先安裝 Visual C++ 2008 Redistributables 各下載版本說明: OpenSSL-Description-20220501.pdf 先安裝 Win64 OpenSSL v1.1.1n.msi. (65 MB) 再安裝 Win64 OpenSSL v3.0.2.msi. (139 MB) ○ 安裝後目錄為 C:\Program Files\OpenSSL-Win64\ ○ 以系統管理員, 開啟 PowerShell, 切換工作目錄到 C:\Program Files\OpenSSL-Win64\ cd "C:\Program Files\OpenSSL-Win64\bin\" ○ 檢查版本: PS C:\Program Files\OpenSSL-Win64\bin> .\openssl version OpenSSL 1.1.1n 15 Mar 2022 注意其他目錄可能也有 openssl.exe, 例如我的電腦中, 有這些 openssl.exe 來自於其他軟體, 版本編號不相同. C:\Program Files\Git\usr\bin\openssl.exe C:\Program Files\Git\mingw65\bin\openssl.exe C:\Program Files\OpenSSL-Win64\tests\openssl.exe C:\Program Files\OpenSSL-Win64\bin\openssl.exe C:\Program Files\VisualSVN Server\bin\openssl.exe ---> 版本編號不同! ○ OpenSSL於2022年3月15日發布安全公告,宣布修補了與憑證解析有相關的嚴重阻斷服務攻擊(Denial of Service, DoS)資安漏洞,建議用戶立即進行更新。 該漏洞的編號為CVE-2022-0778,由Google的研究人員Tavis Ormandy提報給OpenSSL。據OpenSSL官方公告,由於解析憑證時用到的BN_mod_sqrt()函數存在一個問題,在某些情況下駭客可以製作惡意憑證,利用該漏洞使目標系統無法提供服務。 OpenSSL 版本為1.0.2、1.1.1及3.0的用戶會受到該漏洞影響,建議用戶立即更新至版本1.0.2zd、1.1.1n及3.0.2,以免遭到駭客利用此漏洞進行攻擊而造成損失。 CVE編號:CVE-2022-0778 影響產品:OpenSSL 1.0.2、1.1.1及3.0版本。 解決方案: OpenSSL 1.0.2 用戶應升級到 1.0.2zd版本。 OpenSSL 1.1.1 用戶應升級到 1.1.1n版本。 OpenSSL 3.0 用戶應升級到 3.0.2版本。 □ 建立 rootCA20220501.key 憑證授權中心公私鑰(CA RSA Private/public keys) .\openssl genrsa -des3 -out c:\temp\rootCA20220501.key 4096 密碼輸入: (你的密碼), 重複確認後, 就會建立檔案 rootCA20220501.key 在 c:\temp\ 目錄中. rootCA20220501.key 檔案內存放 憑證授權中心公私鑰(RSA Private/public keys). □ 建立 rootCA20220501.crt 憑證授權中心公鑰 或 根憑證(CA RSA public key), 並匯入客戶端本機電腦存放區. 匯入憑證授權中心公鑰到客戶端電腦後, 客戶端電腦 就可信賴 由憑證授權中心 發行的憑證. .\openssl req -config "C:\Program Files\OpenSSL-Win64\bin\openssl.cfg" -x509 -new -nodes -key c:\temp\rootCA20220501.key -sha256 -days 3650 -out c:\temp\rootCA20220501.crt ○ 參數說明: -config 指定 openssl.cfg 檔案位置 -days 有效日數, 3650日=10年. -key 指定 rootCA.key (RSA Private/public keys) -out 要產生的 CA 憑證 rootCA.crt ○ 執行過程及輸入: .\openssl req -config "C:\Program Files\OpenSSL-Win64\bin\openssl.cfg" -x509 -new -nodes -key c:\temp\rootCA20220501.key -sha256 -days 3650 -out c:\temp\rootCA20220501.crt Enter pass phrase for c:\temp\rootCA20220501.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) []:service 011idvtw Common Name (e.g. server FQDN or YOUR name) []:*.011.idv.tw Email Address []:u20220501@gmail.com ○ 客戶端電腦 需信賴 憑證授權中心公鑰 將 (rootCA20220501.crt 憑證授權中心公鑰 或 根憑證(CA RSA public key)) 匯入客戶端電腦存放區 [憑證 - 本機電腦\受信任的根憑證授權單位\憑證] 中 以系統管理員執行 certlm, 匯入 rootCA20220501.crt 到 [憑證 - 本機電腦\受信任的根憑證授權單位\憑證] 中 檢視詳細內容: 簽發者, 主體: E = u20220501@gmail.com CN = *.011.idv.tw OU = service 011idvtw O = 011idvtw L = Taipei S = Taiwan C = TW 有效期自 2022-05-01 11:24:10 有效期到 2032-04-28 11:24:10 主體金鑰識別碼: 291b3e35bed257831f8a50dc2feab8c97864ccc2 授權單位金鑰識別元: KeyID=291b3e35bed257831f8a50dc2feab8c97864ccc2 基本限制(有驚嘆號, 因為只是私密的 CA, 不是公開認證的 CA): Subject Type=CA Path Length Constraint=None 憑證指紋: fa833a2ca40582ba891d906ac326df016114b285 □ 建立 準備憑證要求的設定檔 c:\temp\011idvtw20220501.cnf 內容為 (建立 rootCA20220501.crt 憑證授權中心公鑰 或 根憑證(CA RSA public key))的輸入參數如下: [req] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = 011idvtw [011idvtw] C=TW ST=Taiwan L=Taipei O=011idvtw OU=service 011idvtw emailAddress=u20220501@gmail.com CN=*.011.idv.tw □ 建立 萬用字元的憑證金鑰 檔案 011IdvTw20220501.key .\openssl genrsa -out c:\temp\011IdvTw20220501.key 2048 □ 建立 憑證請求檔案 011IdvTw20220501.csr .\openssl req -new -sha256 -nodes -key c:\temp\011IdvTw20220501.key -out c:\temp\011IdvTw20220501.csr -config c:\temp\011idvtw20220501.cnf □ 建立 V3 設定檔 011idvtw20220501-v3.ext, 內容如下: authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = *.011.idv.tw □ 建立 網站憑證公鑰檔案 011IdvTw20220501.crt .\openssl x509 -req -in c:\temp\011IdvTw20220501.csr -CA c:\temp\rootCA20220501.crt -CAkey c:\temp\rootCA20220501.key -CAcreateserial -out c:\temp\011IdvTw20220501.crt -days 3650 -sha256 -extfile c:\temp\011idvtw20220501-v3.ext 會要求輸入前面的密碼後, 產生 c:\temp\011IdvTw20220501.crt 網站憑證公鑰檔案 □ 將 011IdvTw20220501.crt 轉為 (網站憑證 011IdvTw20220501.pfx) .\openssl pkcs12 -export -out c:\temp\011IdvTw20220501.pfx -inkey c:\temp\011IdvTw20220501.key -in c:\temp\011IdvTw20220501.crt -certfile c:\temp\rootCA20220501.crt 會要求加入(pfx 檔案密碼), 注意別跟前面的密碼一樣! 以上指令可以建立為批次檔(BuildPfx.cmd)內容如下: rem put this file to C:\Certbot\live\[YourDomain]\, e.g. C:\Certbot\live\011.idv.tw\ SET PASSWORD=[YourPassword] "C:\Program Files\OpenSSL-Win64\bin\openssl.exe" pkcs12 -export -out "wild011idvtw20220612.pfx" -inkey "privkey.pem" -in "cert.pem" -certfile "fullchain.pem" -password "pass:%PASSWORD%" □ 將 (網站憑證 011IdvTw20220501.pfx) 匯入本機電腦存放區 以系統管理員執行 certlm, 匯入 (網站憑證 011IdvTw20220501.pfx) 到 [憑證 - 本機電腦\受信任的根憑證授權單位\憑證] 中. 需要輸入(pfx 檔案密碼) 檢視詳細內容: 匯入的圖像會多一把鑰匙, 代表包含私鑰. 簽發者, 主體: (同 rootCA20220501.crt 內容) E = u20220501@gmail.com CN = *.011.idv.tw OU = service 011idvtw O = 011idvtw L = Taipei S = Taiwan C = TW 有效期自 2022-05-01 12:43:21 有效期到 2032-04-28 12:43:21 授權單位金鑰識別元: KeyID=291b3e35bed257831f8a50dc2feab8c97864ccc2 基本限制(無驚嘆號, 因為找的到授權的CA, 也就是前面匯入的 rootCA20220501.crt): Subject Type=End Entity (不是 CA) Path Length Constraint=None 主體別名: DNS Name=*.011.idv.tw 主體金鑰識別碼: a8717db748de6c6abfd10533168acb30080ea081 憑證指紋: ebc41ff37533256df5f32cab016fb0177f292700 ○ 20220612案例, 匯入 Let's Encrypt 憑證: wild011idvtw20220612.pfx 到本機電腦存放區 憑證路徑: ISRG Root X1 ---- R3 -------- *.011.idv.tw 簽章雜湊演算法: sha256 簽發者: CN = R3 O = Let's Encrypt C = US 有效期自 2022-05-29 16:36:52 有效期到 2032-08-27 16:36:51 主體: CN = *.011.idv.tw 主體金鑰識別碼: d26a0412820e95c937170925d16f52bf2640ff0f 授權資訊存取: [1]Authority Info Access Access Method=線上憑證狀態通訊協定 (1.3.6.1.5.5.7.48.1) Alternative Name: URL=http://r3.o.lencr.org [2]Authority Info Access Access Method=憑證授權單位簽發者 (1.3.6.1.5.5.7.48.2) Alternative Name: URL=http://r3.i.lencr.org/ 主體別名: DNS Name=*.011.idv.tw 憑證原則: [1]Certificate Policy: Policy Identifier=2.23.140.1.2.1 [2]Certificate Policy: Policy Identifier=1.3.6.1.4.1.44947.1.1.1 [2,1]Policy Qualifier Info: Policy Qualifier Id=CPS Qualifier: http://cps.letsencrypt.org 基本限制(驚嘆號): Subject Type=End Entity Path Length Constraint=None 憑證指紋: 20e88e8ba4426057e116c07e6743319486a99004 □ 將 (網站憑證 011IdvTw20220501.pfx) 匯入 IIS 伺服器憑證 開啟 IIS 管理介面, 選擇 本機名稱.右邊視窗選伺服器憑證.匯入 憑證檔案: (網站憑證 011IdvTw20220501.pfx) 密碼: (pfx 檔案密碼) 選取憑證儲存區: 個人 允許匯出此憑證: Yes 這樣匯入 跟 (以系統管理員執行 certlm, 匯入到[憑證 - 本機電腦\個人\憑證] 中結果相同. 也就是說, IIS 繫結網站介面中, 可以選擇的憑證儲存區, 就是在 certlm [憑證 - 本機電腦\個人\憑證]. 到這裡發現 Windows 11 的 IIS 伺服器憑證功能中, 有(建立網域憑證...)的選項, 應該也可以建立網域 rootCA ? 可以不用 openssl 建立(待測試) □ 伺服器繫結 (網站憑證 011IdvTw20220501.pfx)到指定的網站 開啟 IIS 管理介面, 選擇 站台.選擇網站.繫結.新增.類型https. IP位址: 全部未指派 連接埠: 443 主機名稱: 空白 SSL 憑證: *.011.idv.tw (要繫結的憑證, 必須經由前一步驟匯入 IIS 伺服器憑證後, 才能選擇.) ○ 20220612錯誤 在複合金鑰屬性 'protocal bindingInformation' 分別設為 'https, *.443:'的情況下, 無法新增類型 'binding'的重複集合項目 □ 用瀏覽器開啟 https 連線測試 例如開啟網址: https://main.011.idv.tw. 注意2個必要條件: 1. 客戶端電腦 需信賴 憑證授權中心公鑰. 客戶端電腦應 將 (rootCA20220501.crt 憑證授權中心公鑰 或 根憑證(CA RSA public key)) 匯入本機電腦存放區 [憑證 - 本機電腦\受信任的根憑證授權單位\憑證] 中. 匯入後, 瀏覽器將會信賴 由 (rootCA20220501.crt 憑證授權中心公鑰 或 根憑證(CA RSA public key)) 發行的憑證. 2. 伺服器網站必須 繫結 網站憑證. IIS 網站管理 需繫結(網站憑證 011IdvTw20220501.pfx) 到網站. ---------- 2022-05-02, 中英對照 CA, Certificate Authority, 憑證授權中心 DER, Distinguished Encoding Rules, (唯一編碼規則)是屬於ASN.1(Abstract Syntax Notation One)標準編碼規則的Basic Encoding Rule(BER)(基本編碼規則)中的一種編碼規則。 root CA, 憑證授權中心根憑證 RSA, 以1977年由 Ron Rivest, Adi Shamir and Leonard Adleman 公開說明的演算法, 因此以三人姓名命名. PFX, Personal Information Exchange, .pfx 檔案, 包含(私鑰及公鑰), Personal Information Exchange. ---------- 2021-12-09 SSL Handshake Process (simplified) ref: https://www.youtube.com/watch?v=JjMfuJOnHzc SSL Handshake Process (simplified) □ SSL Session ○ Uses asymmetric encryption to privately share the session key △ Asymmetric has a lot of overhead △ Not feasible to use for entire session ○ Use symmetric encryption to encrypt the data △ Symmetric encryption is quicker and uses less resources □ SSL Handshake Process (simplified) Step, Client, Process, Server 1. Client: Requests HTTPS session. 2. Server: Certificate sent back (with Public Key). 3. Client: Creates session key (53). 4. Client: Sesson key encrypted with public key (X$qi0). At this point, only client knows session key. 5. Client: Encrypted session key sent to server (X$qi0). 6. Server: Session key decrypted with private key. At this point, both client and server know session key. 7. Session encrypted with symmetric session key (53) □ Q and A Q: What is asymmetric used for in SSL ? A: Privately share the session key. Q: What is symmetric encryption used for in SSL ? A: Encrypt the session data. --------- 2021-12-06 建立 X.509 憑證步驟. ref: CodeHelper\Certificate\VPN Gateway documentation.pdf 中 Generateand export certificates for Point-to-Siteconnections using MakeCert. CodeHelper\cs\KeyWord\SslStreamClass.txt CodeHelper\Certificate\20211127-Authentication\20211127-ServerAuthenticationByClientC#.txt https://docs.microsoft.com/en-us/windows/win32/seccrypto/makecert □ 建立在本機的 開發專用的自我簽核憑證 self signed certificate makecert -sky exchange -r -n "CN=X509Test20211122" -pe -a sha256 -len 2048 -ss My 若非系統管理員權限, 則錯誤如下: Error: Save encoded certificate to store failed => 0x5 (5) Failed 改以系統管理員執行如下, 變更內容為: localhost, root, LocalMachine, 20211128 makecert -sky exchange -r -n "CN=localhost" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk 20211128 以上指令會建立(localhost憑證 儲存在 憑證-目前使用者.受信任的根憑證授權單位.憑證) 中, 發給=localhost, 簽發者=localhost, 到期日=2040/1/1, 使用目的=全部, 易記名稱=無. 建立 "CN=svc.011.idv.tw" 憑證, 注意要在同一台電腦上建立才有效! .\makecert -sky exchange -r -n "CN=svc.011.idv.tw" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk Svc011sk -in Svc011in -b 12/05/2021 -e 12/31/2100 錯誤: Error: Can not specify issuer's private key information for self signed certificate. Please use -sp and -sy instead. 自我簽核憑證 (-in 無法指定)不能指定發行者名稱, 改成如下: 在別台電腦上建立以下憑證後, 匯入 svc.011.idv.tw 電腦, .\makecert -sky exchange -r -n "CN=svc.011.idv.tw" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk Svc011sk -b 12/05/2021 -e 12/31/2100 測試結果, 錯誤: // System.IO.IOException: 解密作業失敗,請查看內部例外狀況。 System.ComponentModel.Win32Exception: 嘗試處理憑證時發生一個不明的錯誤。 於 System.Net.Security.SslStream.Read(Byte[] buffer, Int32 offset, Int32 count) 改在 svc.011.idv.tw 電腦上重新建立: .\makecert -sky exchange -r -n "CN=svc.011.idv.tw" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk Svc011sk -b 12/09/2021 -e 12/31/2101 Error: Can't create the key of the subject ('Svc011sk'), 因為前一個匯入 svc.011.idv.tw 電腦憑證也是這名稱, 不知道該怎麼刪除! 改在 svc.011.idv.tw 電腦上(建立不同的 -sk Svc011k2101: .\makecert -sky exchange -r -n "CN=svc.011.idv.tw" -pe -a sha256 -len 2048 -ss root -sr LocalMachine -sk Svc011sk2101 -b 12/09/2021 -e 12/31/2101 □ 匯出憑證檔案 已系統管理員執行 certmgr 可開啟 (憑證-目前的使用者) ○ 從 目前的使用者儲存區 匯出 public key 檔案: 1. 開啟憑證管理員, 執行 certmgr 後, 選擇 目前的使用者.個人.憑證, 可看到已建立憑證=X509Test20211122, 到期日 2040/1/1. 2. 選擇 所有工作.匯出.否,不要匯出私密金鑰 3. Export File Format 選擇 Base-64 encoded X.509 (.CER檔案) 4. 匯出檔案名稱: C:\temp\X509Test20211122Pub.cer 補充: 由於 .cer 檔案只有公開金鑰, 沒有私密金鑰, 因此後續可不需要特別命名為 Pub. 5. 重複以上步驟, 再匯出 包含 private key 檔案, 因此只能匯出為 .PFX 檔案. 預設匯出選項為: 勾選 如果可能的話, 包含憑證路徑中的所有憑證. 不勾選 如果匯出成功即刪除私密金鑰. 不勾選 匯出所有延伸內容. 勾選 啟用憑證隱私權. 密碼: 20211122 加密: TripleDES-SHA1 (另外可選 AES256-SHA256) 檔案名稱為: C:\temp\X509Test20211122.pfx ○ 從(憑證-目前使用者.受信任的跟憑證授權單位.憑證)中, 匯出憑證(發給=localhost, 簽發者=localhost, 到期日=2040/1/1, 使用目的=全部.) 1. 匯出 20211128.pfx. (包含 passoword 及 public/private key) 2. 匯出 20211128.cer. (不含 private key, 只有 publick key), 使用預設 binary 檔案. 另一選擇為 Base64 文字檔, 可方便剪貼. ○ 從(憑證-目前使用者.受信任的根憑證授權單位.憑證)中, 匯出憑證(發給=svc.011.idv.tw, 簽發者=svc.011.idv.tw, 到期日=2100/12/31, 使用目的=全部.) 預設匯出選項為: 勾選 如果可能的話, 包含憑證路徑中的所有憑證. 勾選 啟用憑證隱私權. 密碼: 20211206 加密: TripleDES-SHA1 (另外可選 AES256-SHA256) 檔案名稱為: C:\temp\X50920211206Svc.pfx △ 匯入(svc.011.idv.tw 電腦之憑證-目前使用者.受信任的根憑證授權單位.憑證) makecert.exe 建立 X.509 憑證 Generateand export certificates for Point-to-Siteconnections using MakeCert ref: https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-certificates-point-to-site-makecert VPN Gateway documentation.pdf // 可利用以下 makecert.exe 建立 X.509 憑證, 存放於 登入使用者 的儲存空間. // makecert -r -pe -n "CN=CERT_SIGN_TEST_CERT" -b 01/01/2010 -e 01/01/2012 -sky exchange -ss my --------- 2021-11-27 摘要 □ 可被信賴的憑證除了必須為 自我簽核憑證 以外, 還必須(被放在可信賴的 Windows Certificate Store 區域中), 或是 (可連結到已經可信賴的憑證) □ 在 HTTPS 網頁中,任何由 HTTP 連結所傳送的 JavaScript 請求都會被禁止。 □ 匯出(自我簽核個人憑證), 可匯出為5種選項: 1. DER encoded binary X.509 (.CER檔案, 只有public key, 無 private key) 2. Base-64 encoded X.509 (.CER檔案, 只有public key, 無 private key) 3. Cryptographic Message Syntax Standard - PKC #7 Certificates (.P7B檔案) 4. Personal Information Exchange - PKCS #12 (.PFX檔案) 5. Microsoft Serialized Certificate Store (.SST檔案) ○ .key (私密金鑰) (使用 PEM 格式) (無密碼保護) ○ .crt (憑證檔案) (使用 PEM 格式) ○ .pfx (PFX 檔案) (使用 PKCS#12 格式) IIS 網站繫結時, 需使用(包含私鑰的 .pfx 檔案, PKCS#12 格式) ○ .pfx 格式的檔案必須設定一組密碼,因此在執行過程中會需要輸入密碼,用以保護這個 *.pfx 檔案. □ Git 內建的 OpenSSL 工具: C:\Program Files\Git\usr\bin\openssl.exe □ 產生 .pfx: openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx □ 匯入自簽憑證到「受信任的根憑證授權單位」 光是建立好自簽憑證,網站伺服器也設定正確,還是不夠的。 這畢竟是一個 PKI 基礎架構,必須所有需要安全連線的端點都能互相信任才行, 因此你還必須將建立好的自簽憑證安裝到「受信任的根憑證授權單位」之中, 這樣子你的作業系統或瀏覽器才能將你的自簽憑證視為「可信任的連線」,以下是不同作業系統平台的設定方式: Windows 請以「系統管理員身分」執行以下命令,即可將憑證匯入到 Windows 的憑證儲存區之中: certutil -addstore -f "ROOT" server.crt 若要以手動方式匯入,可以參考以下步驟: 開啟檔案總管,並滑鼠雙擊 server.crt 檔案 點擊「安裝憑證」按鈕 選取「目前使用者」並按「下一步」繼續 選取「將所有憑證放入以下的存放區」並按下「瀏覽」按鈕 選取「受信任的根憑證授權單位」並按下「確定」 按「下一步」繼續 按「完成」繼續 在 安全性警告 視窗按下「是(Y)」即可完成設定 請注意:在匯入完成後 Google Chrome 瀏覽器可能不會立刻顯示這是個有效憑證 (因為快取的關係),但你只要過一段時間重開 Chrome 瀏覽器,即可看見網址列的變化,不會再出現紅色不安全的提示。 ---------- 20211206 □ 相關指令, 需要有權限. certutil -addstore -f "ROOT" server.crt | 將憑證匯入到 Windows 的憑證儲存區 makecert.exe | 例如 Windows 11 在 C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64 下. Windows 10 在 C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x64 certmgr | 憑證管理員 □ makecert.exe: 例如在 C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64 下. PS C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64> .\makecert -? Usage: MakeCert [ basic|extended options] [outputCertificateFile] Basic Options -sk Subject's key container name; To be created if not present (存放 private key 的名稱, 若未提供則自動建立) -skSubjectKey: Location of the subject's key container which holds the private key. If a key container does not exist, one is created. If neither the -sk or -sv option is used, a default key container is created and used by default. -pe Mark generated private key as exportable. 可匯出 private key. -ss Subject's certificate store name that stores the output certificate -ssSubjectCertStoreName: Name of the subject's certificate store where the generated certificate will be stored. -ss My 建立在使用者自己的儲存區. -ss root 建立在(Windows Certificate Store)的儲存區, (Windows Certificate Store)中的憑證才能作為 可被信賴的憑證除了必須為 自我簽核憑證 以外, 還必須(被放在可信賴的 Windows Certificate Store 區域中), 或是 (可連結到已經可信賴的憑證) -sr Subject's certificate store location. . Default to 'CurrentUser' -srSubjectCertStoreLocation: Registry location of the subject's certificate store. SubjectCertStoreLocation must be either LocalMachine (registry key HKEY_LOCAL_MACHINE) or CurrentUser (registry key HKEY_CURRENT_USER). CurrentUser is the default. -# Serial Number from 1 to 2^31-1. Default to be unique -$ The signing authority of the certificate -n Certificate subject X500 name (eg: CN=Fred Dews) -n "CN=主機名稱": 主機名稱必須與連線主機名稱相同, 才能建立 SSL 連線. -? Return a list of basic options -! Return a list of extended options □ PS C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64> .\makecert -! Usage: MakeCert [ basic|extended options] [outputCertificateFile] Extended Options -tbs Certificate or CRL file to be signed -sc Subject's certificate file -sv Subject's PVK file; To be created if not present, 私鑰檔案, 若未提供則自動建立. -ic Issuer's certificate file -ik Issuer's key container name -iv Issuer's PVK file -is Issuer's certificate store name. -ir Issuer's certificate store location . Default to 'CurrentUser' -in Issuer's certificate common name.(eg: Fred Dews) -a The signature's digest algorithm. . Default to 'sha1' -aAlgorithm: Hash algorithm. Must be set to either SHA-1 or MD5 (default). -ip Issuer's CryptoAPI provider's name -iy Issuer's CryptoAPI provider's type -sp Subject's CryptoAPI provider's name -sy Subject's CryptoAPI provider's type -iky Issuer key type, >. -sky Subject key type, >. -skySubjectKeySpec: Subject's key specification. SubjectKeySpec must be one of three possible values: 1. Signature (AT_SIGNATURE key specification) 2. Exchange (AT_KEYEXCHANGE key specification) 3. An integer, such as 3 -l Link to the policy information (such as a URL) -cy Certificate types, -b Start of the validity period; default to now. -m The number of months for the cert validity period -e End of validity period; defaults to 2039 -h Max height of the tree below this cert -len Generated Key Length (Bits), Default to '2048' for 'RSA' and '512' for 'DSS' -r Create a self signed certificate 開發專用的自我簽核憑證 -nscp Include Netscape client auth extension -crl Generate a CRL instead of a certificate -eku ]> Comma separated enhanced key usage OIDs (憑證目的物件識別碼) // 使用 GARDEN1(使用目的=伺服器憑證), 錯誤為: 伺服器模式 SSL 必須使用具有關聯私密金鑰的憑證。 -? Return a list of basic options -! Return a list of extended options □ PS C:\Users\honda> certutil /? 動詞: -dump -- 傾印設定資訊或檔案 -dumpPFX -- 傾印 PFX 結構 -asn -- 剖析 ASN.1 檔案 -decodehex -- 將十六進位編碼的檔案解碼 -decode -- 將 Base64 編碼的檔案解碼 -encode -- 將檔案以 Base64 編碼 -deny -- 拒絕擱置要求 -resubmit -- 重新提交擱置要求 -setattributes -- 設定擱置要求的屬性 -setextension -- 設定擱置要求的延伸 -revoke -- 撤銷憑證 -isvalid -- 顯示目前的憑證配置 -getconfig -- 取得預設的設定字串 -ping -- 抓取 Active Directory 憑證服務要求介面 -pingadmin -- 抓取 Active Directory 憑證服務管理介面 -CAInfo -- 顯示 CA 資訊 -ca.cert -- 抓取 CA 憑證 -ca.chain -- 抓取 CA 的憑證鏈結 -GetCRL -- 取得 CRL -CRL -- 發佈新的 CRL [或僅限 delta CRL] -shutdown -- 關閉 Active Directory 憑證服務 -installCert -- 安裝憑證授權單位憑證 -renewCert -- 更新憑證授權單位憑證 -schema -- 傾印憑證架構 -view -- 傾印憑證檢視 -db -- 傾印原始資料庫 -deleterow -- 刪除伺服器資料庫資料行 -backup -- 備份 Active Directory 憑證服務 -backupDB -- 備份 Active Directory 憑證服務資料庫 -backupKey -- 備份 Active Directory 憑證服務的憑證及私密金鑰 -restore -- 還原 Active Directory 憑證服務 -restoreDB -- 還原 Active Directory 憑證服務資料庫 -restoreKey -- 還原 Active Directory 憑證服務的憑證及私密金鑰 -importPFX -- 匯入憑證及私密金鑰 -dynamicfilelist -- 顯示動態檔案清單 -databaselocations -- 顯示資料庫位置 -hashfile -- 透過檔案產生並顯示密碼編譯雜湊 -store -- 傾印憑證存放區 -enumstore -- 列舉憑證存放區 -addstore -- 將憑證加入存放區 -delstore -- 從存放區刪除憑證 -verifystore -- 確認存放區中的憑證 -repairstore -- 修復金鑰關聯或更新憑證內容或金鑰安全性描述元 -viewstore -- 傾印憑證存放區 -viewdelstore -- 從存放區刪除憑證 -UI -- 叫用 CryptUI -attest -- 驗證金鑰證明要求 -dsPublish -- 將憑證或 CRL 發佈到 Active Directory -ADTemplate -- 顯示 AD 範本 -Template -- 顯示註冊原則範本 -TemplateCAs -- 顯示範本 CA -CATemplates -- 顯示 CA 範本 -SetCASites -- 管理 CA 的站台名稱 -enrollmentServerURL -- 顯示、新增或刪除 CA 關聯的註冊伺服器 URL -ADCA -- 顯示 AD CA -CA -- 顯示註冊原則 CA -Policy -- 顯示註冊原則 -PolicyCache -- 顯示或刪除註冊原則快取項目 -CredStore -- 顯示、新增或刪除認證存放區項目 -InstallDefaultTemplates -- 安裝預設憑證範本 -URLCache -- 顯示或刪除 URL 快取項目 -pulse -- 脈衝式自動註冊事件或 NGC 工作 -MachineInfo -- 顯示 Active Directory 機器物件資訊 -DCInfo -- 顯示網域控制站資訊 -EntInfo -- 顯示公司資訊 -TCAInfo -- 顯示 CA 資訊 -SCInfo -- 顯示智慧卡資訊 -SCRoots -- 管理智慧卡根憑證 -DeleteHelloContainer -- 刪除 Hello 登入容器。 ** 使用者使用此選項後,必須登出才能使它完成。 ** -verifykeys -- 確認公開/私密金鑰組 -verify -- 確認憑證、CRL 或鏈結 -verifyCTL -- 驗證 AuthRoot 或不允許的憑證 CTL -syncWithWU -- 與 Windows Update 同步 -generateSSTFromWU -- 從 Windows Update 產生 SST -generatePinRulesCTL -- 產生 PIN 規則 CTL -downloadOcsp -- 下載 OCSP 回應並寫入到目錄 -generateHpkpHeader -- 使用所指定檔案或目錄中的憑證來產生 HPKP 標頭 -flushCache -- 在選取的處理序中排清指定的快取,例如 lsass.exe -addEccCurve -- 新增 ECC 曲線 -deleteEccCurve -- 刪除 ECC 曲線 -displayEccCurve -- 顯示 ECC 曲線 -sign -- 重新簽署 CRL 或憑證 -vroot -- 建立/刪除網路虛擬根目錄及檔案共用 -vocsproot -- 建立/刪除 OCSP Web Proxy 的 Web 虛擬根目錄 -addEnrollmentServer -- 新增註冊伺服器應用程式 -deleteEnrollmentServer -- 刪除註冊伺服器應用程式 -addPolicyServer -- 新增原則伺服器應用程式 -deletePolicyServer -- 刪除原則伺服器應用程式 -oid -- 顯示 ObjectId 或設定顯示名稱 -error -- 顯示錯誤碼訊息文字 -getreg -- 顯示登錄值 -setreg -- 設定登錄值 -delreg -- 刪除登錄值 -ImportKMS -- 將使用者金鑰及憑證匯入伺服器資料庫以保存金鑰 -ImportCert -- 將憑證檔案匯入資料庫 -GetKey -- 抓取封存的私密金鑰修復 Blob、產生修復指令碼, 或復原封存的金鑰 -RecoverKey -- 修復備份私密金鑰 -MergePFX -- 合併 PFX 檔案 -ConvertEPF -- 將 PFX 檔案轉換為 EPF 檔案 -add-chain -- (-AddChain) 新增憑證鏈結 -add-pre-chain -- (-AddPrechain) 新增簽署前憑證鏈結 -get-sth -- (-GetSTH) 取得已簽署的樹狀首節點 -get-sth-consistency -- (-GetSTHConsistency) 取得已簽署的樹狀首節點變更 -get-proof-by-hash -- (-GetProofByHash) 透過雜湊取得證明 -get-entries -- (-GetEntries) 取得項目 -get-roots -- (-GetRoots) 取得根目錄 -get-entry-and-proof -- (-GetEntryAndProof) 取得項目和證明 -VerifyCT -- 驗證憑證 SCT -? -- 顯示這個使用訊息 CertUtil -? -- 顯示動詞清單 (命令清單) CertUtil -dump -? -- 顯示 "dump" 命令的說明文字 CertUtil -v -? -- 顯示全部命令的所有說明文字 CertUtil: -? 命令成功完成。 ---------- 20211127 localhost 憑證 正式產品盡量不要使用 localhost 憑證 https://letsencrypt.org/zh-tw/docs/certificates-for-localhost/ 建立 localhost 憑證最好用這個: https://github.com/jsha/minica 最後更新於Dec 21, 2017 | 查看所有文件 有時候,使用者會想要申請網域名稱為 “localhost” 的憑證; 不管是用在本地開發上,或是用在與網頁溝通的原生應用程式上。 Let’s Encrypt 沒有辦法提供 “localhost” 憑證,它不像 “.com” 或 “.net” 一樣在頂級域名底下,因此沒有任何人應該擁有它。 你可以設定網域名稱指向 127.0.0.1,並使用 DNS 驗證方式取得憑證。 然而這事實上是個糟糕的主意,你有其他更好的選擇。 用於本地開發 如果你正在開發網頁,通常會使用本地端的網頁伺服器,例如 Apache 或 Nginx 並在瀏覽器中透過 http://localhost:8000/ 訪問它。 然而瀏覽器在 HTTP 與 HTTPS 網頁上的行為有一點不同。 最主要的差異是:在 HTTPS 網頁中,任何由 HTTP 連結所傳送的 JavaScript 請求都會被禁止。 如果你在本地端使用 HTTP 開發,你的 script 標籤可能一切正常,但是當你部屬到 HTTPS 網站時卻會出現問題。 為了解決這類問題,你應該在本地端的網頁伺服器中使用 HTTPS。 然而你不想要每次打開網頁都看到憑證警告,到底要怎麼樣讓本地瀏覽器顯示綠色小鎖呢? 最好的選擇是:產生自己的憑證,不管是自己簽署,或是由本地根憑證簽屬,並且讓作業系統的憑證信任倉庫信任它。 接著在本地網頁伺服器上使用這個憑證。請參閱下方說明以了解詳細過程。 用於與網頁溝通的原生應用程式 有時候開發者希望一個可下載的原生應用程式,可以與網頁溝通以提供額外的功能。 例如:Dropbox 和 Spotify 桌面板應用程式可以掃描你主機上的文件,這個功能單純的網頁無法做到。 一種常見的解決方法是,在本機的原生應用程式上提供一個網頁伺服器,接著讓網頁透過 XMLHTTPRequest (XHR) 或 WebSockets 的方式與本機伺服器溝通。 大部分的網頁伺服器都使用 HTTPS,這表示瀏覽器會禁止你透過 XHR 或 WebSockets 向不安全的連結發送請求; 這稱為 Mixed Content Blocking。 原生伺服器必須提供安全的網頁服務,才能讓網頁與它溝通。 幸運的是,現今的瀏覽器認為 http://127.0.0.1:8000/ 是一個可能可以信任的連結,因為它指向 loopback 位置。 送到 127.0.0.1 的流量保證不會離開你的主機,因此瀏覽器認為,相較於網路環境可能受擷取,這個連結相對安全。 並且如果你的原生應用程式在 127.0.0.1 上提供網頁服務,則兩者就能透過 XHR 互相溝通。 而不幸的是,localhost 這個域名並沒有受到瀏覽器的特殊規則影響,並且 WebSockets 在兩個域名上都沒有這項特殊規則。 你可能想透過以下方式繞過這些限制: 在全域的 DNS 中添加一個網域名稱(例如 localhost.example.com)並指向 127.0.0.1,取得該網域的憑證後, 將該憑證和對應的私鑰放入原生應用程式中,並且告訴網頁與 https://localhost.example.com:8000/ 而不是 http://127.0.0.1:8000/ 溝通。 請不要這麼做,這樣會導致你的使用者暴露在危險之中,而你的憑證也可能被註銷。 如果你使用網域名稱而不是 IP 位置,攻擊者可以透過對 DNS 查詢進行中間人攻擊 (MitM),將網域名稱指向另一個 IP 位置。 攻擊者可以偽裝成本地端的應用程式,接著傳送一個假的回應給網頁,這可能會造成網頁的帳號遭入侵。 你可能會為了讓你的原生應用程式可以運作,而將私鑰和憑證放入原生應用程式中,這直接造成了中間人攻擊的可能性。 因為任何人包括攻擊者,都可以下載並複製你在原生應用程式中的私鑰。 如果發現了洩漏私鑰的情況,你的憑證管理機構必須註銷你的憑證。 不少原生應用程式他們的憑證都因為洩漏私鑰而被註銷。 不幸的是,原生應用程式缺乏缺少安全的方式與對應的網頁溝通。 在未來瀏覽器可能會限制 localhost 瀏覽器對 localhost 的存取,使得互相溝通變得更加困難。 此外也請注意,在原生應用程式中提供包含特殊權限的 API 本身就存在風險,因為沒有你授權的網站也可以訪問它。 如果你還是想要這麼做,請務必閱讀跨來源資源共用頁面,使用 Access-Control-Allow-Origin,並確保使用記憶體安全的 HTTP 語法分析器, 因為即使你限制訪問的網站來源,攻擊者也可能透過分析器的漏洞,向你的 API 傳送特殊權限的請求。 產生並信任你自己的憑證 每個人都可以產生自己的憑證,不需要憑證頒發機構。 唯一的差別是你製作的憑證不會被其他人所信任。 不過對於本地開發環境的需求,這樣就足夠了。 產生私鑰與自簽憑證最簡單的方式就是使用以下 openssl 指令: openssl req -x509 -out localhost.crt -keyout localhost.key \ -newkey rsa:2048 -nodes -sha256 \ -subj '/CN=localhost' -extensions EXT -config <( \ printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") 你可以透過使用 localhost.crt 和 localhost.key 設定本地網頁伺服器,並在將 localhost.crt 安裝到受信任的本地根憑證中。 如果你想要更真實的本地端憑證,你可以使用 minica 產生你的本地根憑證,並利用它頒發終端憑證(子葉憑證)。 你就可以引入 根憑證 而不是引入自簽的終端憑證。 你也可以透過 /etc/hosts 將 www.localhost 設定為 127.0.0.1 的別名。 這會讓瀏覽器儲存 cookie 的方式有一點改變。 ---------- 20200123 ref: 使用 OpenSSL 製作萬用字元 SSL 憑證 https://blog.darkthread.net/blog/issue-wildcard-ssl-cert-with-openssl/ 使用OpenSSL建立CA及簽發SSL憑證 https://blog.darkthread.net/blog/iis-ssl-cert-by-openssl/ ---------- 使用 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 憑證簽發其他伺服器憑證,記得妥善保存相關檔案及密碼。 ---------- 使用OpenSSL建立CA及簽發SSL憑證, 2013-05-17, 舊 https://blog.darkthread.net/blog/iis-ssl-cert-by-openssl/ 之前曾討論過WebClient存取使用自我簽署憑證的SSL連結,會發生以下錯誤: The underlying connection was closed: Could not establish trust relationship for SSL/TLS secure channel. / 基礎連接已關閉: 無法為 SSL/TLS 安全通道建立信任關係。 需透過ServerCertificateValidationCallback克服。 最近又遇到類似情境,但Client程式是別人寫的,修改有困難。 決定嘗試另一種做法: 自己搞一個CA,讓Windows信任該CA,如此該CA簽發的憑證直接被視為有效,就可避免前述問題。 Windows Server有Active Directory 憑證服務,缺點是綁了AD權限, 不想在正式伺服器亂擺測試用途資料,為此架測試用AD又有點為了喝牛奶養牛, 故決定使用獨立軟體工具來處理,OpenSSL,自然是首選。 第一步是下載與安裝OpenSSL。 身為C語言麻瓜,沒興趣也沒信心挑戰在Windows平台編譯OpenSSL, 當機立斷衝到OpenSSL for Windows下載編譯好的版本。網站的版本很多, 我選擇了Win32 OpenSSL v1.0.1e(OpenSSL作者建議開發者安裝的版本), 但安裝前要先裝Visual C++ 2008 Redistributables。 安裝完成後,在安裝目錄(我的例子是X:\Tools\OpenSSL)的bin目錄下,可以找到openssl.cfg,修改其中CA相關設定: dir = ./PEM/darkCA (要放CA資料的目徑,要手動建目錄及檔案,後面會提) default_days = 3650 (預設365,改成十年比較省事) (以下的預設值請自行依個人狀況調整) countryName = TW countryName_default = TW stateOrProvinceName = Taiwan stateOrProvinceName_default = Taiwan localityName = Taipei 0.organizationName = Darkthread 0.organizationName_default = Darkthread organizationalUnitName = HQ commonName = darkthread.net (具有識別性的名稱,FQDN也是好選擇) emailAddress = nobody@ mail.com.tw 接著準備CA專用資料夾: 在bin/PEM下建立CA專屬的資料夾,本範例為darkCA 建立bin/PEM/darkCA/private,放私鑰用 建立bin/PEM/darkCA/newcerts,放簽發的憑證 建立一個文字檔案bin/PEM/darkCA/serial(無附檔名),在其中寫入1000,或者可以用echo 1000 > serial建立,該數字被用來產生簽發憑證流水號 建立一個全空的文字檔bin/PEM/darkCA/index.txt,保存簽發憑證記錄用 下一步,開啟CMD.EXE準備動手。為了省去每次執行工具都要指定openssl.cfg的麻煩,先設定目錄變數 set OPENSSL_CONF=x:\tools\openssl\bin\openssl.cfg 使用以下指令建立CA憑證,參數剛才在openssl.cfg都寫好了,除了PEM密碼,其餘幾乎都可以按Enter用預設值。 X:\Tools\OpenSSL\bin>openssl req -new -x509 -days 3650 -extensions v3_ca -keyout PEM/darkCA/private/cakey.pem -out PEM/darkCA/cacert.pem Loading 'screen' into random state - done Generating a 1024 bit RSA private key ..........++++++ .......++++++ writing new private key to 'PEM/darkCA/private/cakey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- 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. ----- TW [TW]: Taiwan [Taiwan]: Taipei []: Darkthread [Darkthread]: HQ []: darkthread.net []: nobody @mail.com.tw []: 此時,bin/PEM/darkCA/cacert.pem就建好了,可以開始用它簽發SSL憑證給IIS囉! 取得IIS憑證要求檔(產生步驟請參考保哥的文章),再用openssl產生SSL憑證: (註: openssl.cfg中預設憑證要求檔所輸入的國家、州省、組織名稱必須與CA一致,此點可修改openssl.cfg的[ policy_match ]設定放寬) X:\Tools\OpenSSL\bin>openssl ca -out iisCert.pem -in webRequest.txt Using configuration from x:\tools\openssl\bin\openssl.cfg Loading 'screen' into random state - done Enter pass phrase for ./PEM/darkCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 4096 (0x1000) Validity Not Before: May 15 04:13:22 2013 GMT Not After : May 13 04:13:22 2023 GMT Subject: countryName = TW stateOrProvinceName = Taiwan organizationName = Darkthread organizationalUnitName = HQ commonName = localhost X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: C3:8A:CD:2D:69:0C:2F:B3:1C:68:3E:31:11:8A:EA:9B:01:13:74:3A X509v3 Authority Key Identifier: keyid:72:F8:85:B1:D0:42:EF:EB:3D:C3:2E:B5:C1:FD:E8:AA:B0:52:91:A1 Certificate is to be certified until May 13 04:13:22 2023 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated 接著依前述文章的第4步說明,將bin/PEM/darkCA/newcerts/iisCert.pem當成CA送回結果進行"完成憑證"作業,我們這個地下CA所簽發的憑證就在IIS裝好了。不過此時使用SSL連線還是會彈出警告,原因是我們的電腦尚未信任地下CA的根憑證。 開啟IE的網際網路選項,依圖中的(1)到(4),選取【憑證】/ 【受信任的根憑證單位】 / 【匯入】,再指向bin/PEM/darkCA/cacert.pem,按下一步開始匯入。 由於匯入根憑證非同兒戲,Windows會再次詢問確認: "你願意嗎?" "Yes, I do." (提醒: 匯入任何根憑證前請確認憑證來源安全無虞,以免埋下禍害) 完成後,原先用OpenSSL簽發的憑證就會視為有效,但憑證Cache會影響結果,請重新開機或使用第一張圖的【清除SSL狀態】鈕(紅色標示區)清除再做測試。此時可發現,IE已不再跳出任何警告,WebClient取存時也不再出錯囉~ 【資安提醒】 經以上操作,自訂CA簽發的憑證都會被Windows直接判定有效,有可能惡意程式也藉此通過檢查獲得更大權限,為避免遭到誤用危險安全,請務必保管好自訂CA憑證及密碼並不要輕信來路不明的憑證。 【延伸參考】Creating an SSL Certificate of Authority