﻿# 如何使用 MakeCert 建立開發測試用途的自簽憑證 (Self-Signed Certificate)

無論我們開發網站或撰寫應用程式，都有可能會需要手動建立測試用的憑證，好讓我們的測試環境可以有效模擬像是 TLS/SSL 連線、發送 S/MIME 郵件、簽署應用程式、... 等等。這篇文章我想來示範如何用 MakeCert 工具，來幫助大家快速建立自簽憑證，並學習幾個重要的憑證觀念。

在標準的 [PKI](https://en.wikipedia.org/wiki/Public_key_infrastructure) (公開金鑰基礎建設) 基礎架構下，當我們需要一張 **數位憑證** (Digital Certificate)，正常都需要先建立一個 **憑證授權單位** (CA)，然後需要 **憑證** (Certificate) 的 **實體** (Entity) ( 可能是人、系統、公司、組織、應用程式、... ) 需要先建立一個 [CSR](https://en.wikipedia.org/wiki/Certificate_signing_request) (憑證簽署請求) 檔，再將 CSR 檔提交給 CA 進行審核，主要是審核這個「**實體**」的 **真實身分** (Identity)，如果確認身分無誤，就會透過這個 CA 核發一張 **數位憑證** (Digital Certificate) 給這個 **實體** (Entity)。

以上描述可以追加一些技術細節如下：

-   **數位憑證架構**主要是使用 [**公開金鑰加密**](https://zh.wikipedia.org/wiki/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86) ([Public key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography)) 或稱 **非對稱加密** (Asymmetrical cryptography) 機制。
-   所以每張 **憑證** (Certificate) 都需要一把 **公開金鑰** (Public Key) 與一把 **私密金鑰** (Private Key)，以實現 **非對稱加密** (Asymmetrical cryptography) 機制。
-   建立一個 **憑證授權單位** (CA) 本身也需要一個 **憑證** (Certificate)，因此建立這張憑證也需要一把 **公開金鑰** (Public Key) 與一把 **私密金鑰** (Private Key)。
-   建立一個 **憑證簽署請求** (CSR) 主要是建立一把 **公開金鑰** (Public Key) 與 **憑證主體資訊** (Subject)，並透過自己的 **私密金鑰** (Private Key) 進行簽章確認。
-   當 **憑證授權單位** (CA) 收到 CSR 檔之後，就可以透過 **憑證授權單位** (CA) 的 **私密金鑰** (Private Key) 搭配 **憑證簽署請求** (CSR) 產生一個全新的 **憑證** (Certificate)。
-   每張 **憑證** (Certificate) 通常都會包含一把 **公開金鑰** (Public Key) 與一些 **附加資訊** (Metadata)，這裡的附加資訊就包含了許多憑證的重要資訊，如下圖示：  
    [![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2f719cc195a9f6c2325a-image_thumb_247.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/552632053a225b54fca6-image_3115.png)

由於所有合法有效的憑證，都必須由 CA 進行簽發，才能獲得電腦的「信任」。那麼為什麼我們的電腦會信任由這些 CA 所簽發的憑證呢？因為每一個作業系統，都會在出廠的時候，預設就會內建一些「**受信任的根憑證授權單位**」(Trusted Root CA) 在你的電腦中，所以只要由這些**受信任的根憑證**所簽發的**憑證**，預設就是「受信任的憑證」。

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/87e1e5a71f616f18cc66-image_thumb_248.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/40bb8603a7b5985939c9-image_3116.png)

這時問題就來了，我們的受信任的**根憑證** (Root Certificate)，又是由**哪一張憑證**負責簽發的呢？是的！**根憑證**基本上就是**自行簽發的憑證**，又稱「**自簽憑證**」( [Self-Signed Certificate](https://en.wikipedia.org/wiki/Self-signed_certificate) )。

「**自簽憑證**」無法確認「**實體**」的 **真實身分** (Identity)，因為簽發這張憑證的人就是他自己本身。所以你無法真正的確認這張憑證到底是由誰發出的，因為每個人本來都能夠建立自簽憑證，光從憑證中的資訊去判斷，是無法驗證真偽的。這就是為什麼作業系統在出廠的時候，要預先內建「**受信任的根憑證授權單位**」(Trusted Root CA) 的原因，因為這些憑證是世界公認「受信任」的自簽憑證。

當然，你也可以自行建立一張「**自簽憑證**」( [Self-Signed Certificate](https://en.wikipedia.org/wiki/Self-signed_certificate) )，並自己將該憑證加入到「**受信任的根憑證授權單位**」(Trusted Root CA) 中，你的電腦就能預設信任所有由該憑證簽發的所有憑證。

現在，我們就先透過一套年代久遠的憑證建立工具 [MakeCert](https://learn.microsoft.com/zh-tw/windows-hardware/drivers/devtest/makecert) 來建立一張「自簽憑證」，這套工具主要的用途就是幫你建立各種 [X.509](https://en.wikipedia.org/wiki/X.509) 相容的憑證，以下是幾種常見的用法：

**1\. 建立一張測試用的憑證，並將憑證儲存在檔案系統**

以下命令會自動建立一張檔名為 **test.cer** 的憑證，所有憑證資訊都是預設值，預設名稱為 **Joe's-Software-Emporium**。但這不算是自簽憑證，而是用 Windows 內建的**測試用根憑證**幫你簽發的一張新憑證。

> **MakeCert test.cer**
> 
> [![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/9c5e867b8c82bda7e443-image_thumb_249.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/43c94d3bacefe802fe8b-image_3117.png)

**2\. 建立一張測試用的憑證，並將憑證儲存在系統的「憑證儲存區」(Certificate Store)**

以下命令會自動建立一張名為 **Joe's-Software-Emporium** 的新憑證，跟上一個命令一樣，差別只在於你在目錄下看不到實際的憑證檔案，因為該檔案被儲存在 Windows 作業系統內的「**憑證儲存區**」(Certificate Store) 中。請注意：這裡 **\-ss** 參數指定的 **My** 指的是「**個人**」的憑證儲存區。如果你設定 **\-ss** 為 **Root** 就代表要將憑證寫入到「**受信任的根憑證授權單位**」的憑證儲存區。

> **MakeCert -ss My**

**3\. 建立一張測試用的憑證，將憑證儲存在系統的「憑證儲存區」(Certificate Store)，並設定私密金鑰可以匯出**

以下命令會自動建立一張名為 **Joe's-Software-Emporium** 的新憑證，除了可以註冊進「**憑證儲存區**」(Certificate Store) 之外，還可以標示該憑證的**私密金鑰**是可以**允許匯出**的。

> **MakeCert -ss My -pe**

**4\. 建立一張測試用的憑證，主體名稱設定為 blog.miniasp.com，並同時產生私密金鑰與憑證檔案**

以下命令會自動建立一張名為 **blog.miniasp.com** 的新憑證，並且將除 **私密金鑰** 與 **憑證** 都儲存在檔案系統裡。這張憑證一樣是由系統內建的測試根憑證幫你簽發的。

> **MakeCert -n "CN=blog.miniasp.com" -sv blog.miniasp.com.pvk blog.miniasp.com.cer**

由於透過 MakeCert 產生的**簽章雜湊演算法**為強度較弱的 **SHA1**，這個雜湊演算法已經被許多應用程式視為不安全等級，如果要使用高強度的 **SHA256** 簽章雜湊演算法，只要加入 **\-a SHA256** 參數即可。

**5\. 建立一張測試用的憑證，主體名稱設定為 blog.miniasp.com，並將私密金鑰儲存到金鑰容器 (Key Container)，將憑證儲存到檔案系統**

這裡的 **\-sk** 參數是設定一個 **金鑰容器** 的名稱，並將 **私密金鑰** 儲存到該 **金鑰容器** 中，用這種方式儲存**私密金鑰**會比儲存到**檔案系統**相對來的安全許多！因為儲存在**金鑰容器**中的**私密金鑰**只能透過 [CryptoAPI](https://en.wikipedia.org/wiki/Microsoft_CryptoAPI) 來取得相關資訊，微軟並沒有提供任何命令列工具幫你單獨匯出私密金鑰。不過也有人寫了個 [KeyPal](http://forum.ultravnc.info/viewtopic.php?t=13689) 工具 ([Source Code](https://github.com/doggy8088/KeyPal)) 幫你管理 **金鑰容器**。想了解更深入，可以參考 [Key Storage and Retrieval](https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778\(v=vs.85\).aspx) 文件。

> **MakeCert -n "CN=blog.miniasp.com" \-sk MyKey blog.miniasp.com.cer**

**6\. 建立一張測試用的「自簽憑證」，主體名稱設定為 blog.miniasp.com，並同時產生私密金鑰與憑證檔案**

以下命令會自動建立一張名為 **blog.miniasp.com** 的新憑證，並且將除 **私密金鑰** 與 **憑證** 都儲存在檔案系統裡。由於我們加上了 **\-r** 參數，所以你將會產生一份「自簽憑證」，所以你可以看到「簽發者」的名稱將會跟「主體名稱」一樣，如下圖示：

> **MakeCert -n "CN=blog.miniasp.com" -sv blog.miniasp.com.pvk blog.miniasp.com.cer \-r**
> 
> [![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/3662d5c5371accd72140-image_thumb_250.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/686cd11ff1dfc507b584-image_3118.png)

**7\. 建立一張測試用的「自簽憑證」，主體名稱設定為 localhost，並將憑證註冊到「受信任的根憑證授權單位」的憑證儲存區，而且私密金鑰可以匯出**

> **MakeCert -n "CN=blog.miniasp.com" -ss Root -r -pe**

**8\. 建立一張測試用的「自簽憑證」，主體名稱設定為 miniasp.com，並將憑證註冊到「本機電腦憑證」下的「個人」的憑證儲存區，而且私密金鑰可以匯出**

> **MakeCert -n "CN=miniasp.com" -ss My -r -pe -sr localmachine**

**9\. 建立一張測試用的「自簽憑證」，憑證到期日設定為 2025/12/31 00:00:00，主體名稱設定為 miniasp.com，並將憑證註冊到「本機電腦憑證」下的「個人」的憑證儲存區，而且私密金鑰可以匯出**

預設透過 MakeCert 產生的憑證，憑證有效期間為 **當下時間** 到 **12/31/2039 11:59:59 GMT**，當你想明確指定起訖時間，可以加入 **\-b** 與 **\-e** 參數。通常都不會特別加上 **\-b** 參數。

> **MakeCert -n "CN=miniasp.com" -ss My -r -pe -sr localmachine -e 12/31/2025**

**10\. 建立一張測試用的「自簽憑證」，憑證到期日設定為 2025/12/31 00:00:00，RSA 加密等級提升為 2048 Bits，主體名稱設定為 miniasp.com，並將憑證註冊到「本機電腦憑證」下的「個人」的憑證儲存區，而且私密金鑰可以匯出**

由於 MakeCert 是一套老牌的憑證工具，預設 RSA 加密等級只有 1024 而已，你可以透過 **\-len** 參數將**金鑰長度**提升至 **2048** 或 **4096** bits 等等。現在的憑證一般都建議金鑰長度至少 2048 bits 以上。

> **MakeCert -n "CN=miniasp.com" -ss My -r -pe -sr localmachine -e 12/31/2025 -len 2048**

一般來說，每一張憑證都會有一個以上的用途。以我們上述的命令所建立的憑證，都屬於「沒有明確指定用途」的憑證，預設等同於可以用來當成所有用途的憑證。

例如你想在你的網站伺服器安裝 TLS/SSL 憑證，那麼你就有可能會想建立一張專門用來給 IIS 或 Apache 使用的伺服器憑證。此時你就可以在建立自簽憑證的時候，直接標註用途為 **伺服器驗證**([serverAuth](https://oid-base.com/get/1.3.6.1.5.5.7.3.1))。這部分在 MakeCert 工具下，就要加入 **\-eku** 參數 (**EKU** = **Extended Key Usage** = **增強型密鑰用法**)，並指定正確的 [OID](https://en.wikipedia.org/wiki/Object_identifier) (物件識別碼)。在建立憑證時常見的 OID 如下：

-   [1.3.6.1.5.5.7.3.1](https://oid-base.com/get/1.3.6.1.5.5.7.3.1) - 伺服器驗證 (serverAuth)
-   [1.3.6.1.5.5.7.3.2](https://oid-base.com/get/1.3.6.1.5.5.7.3.2) - 用戶端驗證 (clientAuth)
-   [1.3.6.1.5.5.7.3.3](https://oid-base.com/get/1.3.6.1.5.5.7.3.3) - 程式碼簽署 (codeSigning)
-   [1.3.6.1.5.5.7.3.4](https://oid-base.com/get/1.3.6.1.5.5.7.3.4) - 電子郵件加密 (emailProtection)
-   [1.3.6.1.5.5.7.3.8](https://oid-base.com/get/1.3.6.1.5.5.7.3.8) - 時戳簽章 (timeStamping)

如果我們想建立一張可以給 IIS 網站伺服器專用的自簽憑證，就可以用以下命令快速建立：

> **MakeCert -n "CN=blog.miniasp.com" -ss My -r -pe -sr localmachine -eku 1.3.6.1.5.5.7.3.1**

**請注意**：你必須將憑證註冊在 **LocalMachine** 才能讓 IIS 選到這個憑證。如果你沒有指定 -eku 參數，也可以從 IIS 選中這張憑證，因為沒有設定參數就是一張萬用的憑證。但如果你將 **\-eku** 設定為 [1.3.6.1.5.5.7.3.2](https://oid-base.com/get/1.3.6.1.5.5.7.3.2) (clientAuth) 的話，IIS 在選取憑證的時候，就不會看見這張憑證。

除了憑證可以指定用途以外，其實還能設定「**憑證類型**」(Certificate Type)，大致區分兩類：

1.  **end** (終端實體)

-   這種類型的憑證，主要用在實際的系統或應用程式中。

3.  **authority** (憑證授權單位)

-   這種類型的憑證，主要用在 CA 憑證授權單位中，用來簽發其他 end 憑證之用。

**請注意**：如果你沒有特別設定，該憑證一樣也是萬用憑證，兩種類型都可以用。

如果你想建立一張 CA 的自簽憑證，可以用以下方式建立：

> **MakeCert -n "CN=Will CA Root" -ss Root -r -pe -sr localmachine -cy authority**

如下圖示：

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/637bf5833da35a79f0a7-image_thumb_251.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2cb6ce63b5f066379669-image_3119.png)

**相關連結**

-   [MakeCert (Windows)](https://msdn.microsoft.com/en-us/library/aa386968.aspx)
-   [Using MakeCert (Windows)](https://msdn.microsoft.com/en-gb/library/aa388165.aspx)
-   [Asymmetric encryption - Simply explained - YouTube](https://youtu.be/AQDCe585Lnc)
-   [強制版伺服器數位憑證介紹 (SGC SSL)](https://www.ssl.com.tw/Products/ssl-certificate-products/SGCSSL.html)
