03-3. 數位憑證與 CA

⏱️ 閱讀時間: 12 分鐘 🎯 難度: ⭐⭐ (簡單)


🎯 本篇重點

深入理解數位憑證的結構、CA(憑證機構)的角色、憑證申請流程、信任鏈的運作方式,以及如何處理憑證問題。


🤔 什麼是數位憑證?

Digital Certificate(數位憑證) = 網站的「數位身份證」

一句話解釋: 數位憑證就像是身份證,證明「這個網站確實是它所聲稱的網站」,由可信任的第三方(CA)發行和簽章。


🎫 用身份證來比喻數位憑證

身份證(政府發行)

身份證內容:
├─ 姓名:張三
├─ 生日:1990-01-01
├─ 身份證號:A123456789
├─ 照片:📸
└─ 發行機關:內政部 🏛️(政府簽章 ✅)

特性:
- 由政府發行(可信任)
- 有政府簽章(防偽造)
- 過期需要更新
- 用來證明你的身份

驗證:
警察:請出示身份證
你:這是我的身份證 🎫
警察:檢查簽章...✅ 是真的

數位憑證(CA 發行)

數位憑證內容:
├─ 網域名稱:www.google.com
├─ 公鑰:[RSA 2048-bit public key]
├─ 有效期:2024-01-01 to 2025-01-01
├─ 發行者:Google Trust Services LLC
└─ CA 數位簽章:✅

特性:
- 由 CA 發行(可信任)
- 有 CA 數位簽章(防偽造)
- 過期需要更新
- 用來證明網站的身份

驗證:
瀏覽器:請出示憑證
網站:這是我的憑證 📜
瀏覽器:檢查 CA 簽章...✅ 是真的

📜 數位憑證的結構

X.509 憑證格式

數位憑證包含:

1. 版本資訊
   - X.509 v3

2. 序號
   - 唯一識別碼
   - 例:03:2E:7F:2F:5F:AC:1C:34...

3. 簽章演算法
   - sha256WithRSAEncryption
   - ecdsa-with-SHA256

4. 發行者(Issuer)
   - 哪個 CA 發行
   - CN=Let's Encrypt Authority X3

5. 有效期(Validity)
   - 不早於(Not Before):2024-01-01 00:00:00 UTC
   - 不晚於(Not After):2025-01-01 23:59:59 UTC

6. 主體(Subject)
   - 憑證擁有者
   - CN=www.example.com

7. 公鑰資訊(Subject Public Key Info)
   - 演算法:RSA 2048-bit
   - 公鑰:[public key data]

8. 擴充欄位(Extensions)
   - Subject Alternative Name(SAN)
     - www.example.com
     - example.com
     - *.example.com
   - Key Usage(金鑰用途)
     - Digital Signature
     - Key Encipherment
   - Extended Key Usage
     - TLS Web Server Authentication
   - Authority Information Access(AIA)
     - OCSP:http://ocsp.example.com
   - CRL Distribution Points
     - http://crl.example.com/crl.pem

9. CA 數位簽章
   - CA 用私鑰簽署整個憑證
   - [signature data]

查看憑證(Chrome)

步驟:
1. 打開 https://www.google.com
2. 點擊網址列的 🔒
3. 點擊「憑證」

可以看到:
┌─────────────────────────────────┐
│ 一般                              │
├─────────────────────────────────┤
│ 發給:www.google.com            │
│ 發行者:WR2                      │
│ 有效期:2024-12-02 到 2025-02-24  │
├─────────────────────────────────┤
│ 詳細資料                          │
├─────────────────────────────────┤
│ 版本:V3                         │
│ 序號:0D:B9:64:72:0A:E9:81:98   │
│ 簽章演算法:ecdsa-with-SHA256    │
│ 發行者:CN=WR2, O=Google Trust...│
│ 有效期從:2024-12-02             │
│ 有效期到:2025-02-24             │
│ 主體:CN=www.google.com          │
│ 主體公開金鑰:ECDSA 256 bits    │
└─────────────────────────────────┘

使用 OpenSSL 查看憑證

# 查看線上網站的憑證
echo | openssl s_client -servername www.google.com \
  -connect www.google.com:443 2>/dev/null | \
  openssl x509 -noout -text

# 輸出範例:
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0d:b9:64:72:0a:e9:81:98
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=Google Trust Services LLC, CN=WR2
        Validity
            Not Before: Dec  2 08:28:44 2024 GMT
            Not After : Feb 24 08:28:43 2025 GMT
        Subject: CN=www.google.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:www.google.com
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
    Signature Algorithm: ecdsa-with-SHA256

🏛️ CA(憑證機構)的角色

什麼是 CA?

CA (Certificate Authority) = 憑證機構

角色:
- 數位世界的「公證人」
- 驗證身份並發行憑證
- 用數位簽章證明憑證真實性

比喻:
CA 就像是政府的「戶政事務所」
- 驗證你的身份
- 發行身份證
- 政府簽章證明真實性

CA 的類型

1. 根 CA(Root CA)
   - 最高層級的 CA
   - 自己簽署自己的憑證(Self-Signed)
   - 瀏覽器內建信任

   範例:
   ├─ DigiCert Global Root CA
   ├─ Let's Encrypt ISRG Root X1
   ├─ GlobalSign Root CA
   └─ Comodo CA

2. 中繼 CA(Intermediate CA)
   - 由根 CA 簽發
   - 實際簽發網站憑證

   範例:
   根 CA(DigiCert)
       ↓ 簽發
   中繼 CA(DigiCert TLS RSA SHA256 2020 CA1)
       ↓ 簽發
   網站憑證(www.example.com)

3. 為什麼需要中繼 CA?
   - 保護根 CA 私鑰(離線保存)
   - 根 CA 私鑰洩露影響巨大
   - 中繼 CA 可以撤銷並重新發行

信任鏈(Chain of Trust)

完整的信任鏈:

瀏覽器內建根 CA
    ↓ 信任
根 CA 憑證(DigiCert Global Root CA)
    ↓ 簽發
中繼 CA 憑證(DigiCert TLS RSA SHA256 2020 CA1)
    ↓ 簽發
網站憑證(www.example.com)

驗證流程:
1. 網站提供:網站憑證 + 中繼 CA 憑證
2. 瀏覽器檢查:
   ├─ 網站憑證由中繼 CA 簽發 ✅
   ├─ 中繼 CA 憑證由根 CA 簽發 ✅
   └─ 根 CA 在瀏覽器信任清單中 ✅
3. 信任成功 ✅

如果任一環節失敗:
❌ 憑證無效
⚠️ 瀏覽器警告

📋 憑證申請流程

完整流程

【第 1 步:產生金鑰對】
網站管理員(在伺服器上):
openssl genrsa -out private.key 2048

產生:
- 私鑰(private.key)← 絕對保密
- 公鑰(包含在 CSR 中)

【第 2 步:產生 CSR(憑證簽署請求)】
openssl req -new -key private.key -out request.csr

填寫資訊:
- Country Name: TW
- Organization: Example Inc.
- Common Name: www.example.com
- Email: admin@example.com

產生:
- CSR 檔案(request.csr)
- 包含公鑰和網站資訊

【第 3 步:提交 CSR 給 CA】
網站管理員 → CA:
- 上傳 CSR
- 選擇憑證類型
- 付款(商業 CA)

【第 4 步:CA 驗證網域擁有權】
CA 的驗證方式:

方法 1:檔案驗證
CA:請在網站放置檔案
    http://example.com/.well-known/acme-challenge/TOKEN
網站:放置檔案
CA:訪問檔案...✅ 驗證成功

方法 2:DNS 驗證
CA:請新增 DNS TXT 記錄
    _acme-challenge.example.com TXT "TOKEN"
網站:新增 DNS 記錄
CA:查詢 DNS...✅ 驗證成功

方法 3:Email 驗證(DV 憑證)
CA:發送驗證郵件到
    admin@example.com
    webmaster@example.com
網站:點擊驗證連結...✅ 驗證成功

【第 5 步:CA 簽發憑證】
CA:
1. 驗證通過 ✅
2. 用 CA 私鑰簽署憑證
3. 產生數位憑證

CA → 網站:
- 數位憑證(certificate.crt)
- 中繼 CA 憑證(intermediate.crt)

【第 6 步:安裝憑證到伺服器】
網站管理員:
- 上傳憑證到伺服器
- 設定 Web 伺服器(Nginx/Apache)
- 重啟伺服器

完成!🎉

Let’s Encrypt 自動化流程

Let's Encrypt = 免費、自動化的 CA

使用 Certbot 自動申請:

# 安裝 Certbot
sudo apt-get install certbot python3-certbot-nginx

# 自動申請憑證(Nginx)
sudo certbot --nginx -d example.com -d www.example.com

Certbot 自動完成:
1. 產生金鑰對 ✅
2. 產生 CSR ✅
3. 提交給 Let's Encrypt ✅
4. 自動驗證(HTTP-01 或 DNS-01)✅
5. 取得憑證 ✅
6. 設定 Nginx ✅
7. 重啟 Nginx ✅

輸出:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem

自動更新(每 90 天):
sudo certbot renew --dry-run

設定 cron job:
0 0 * * * certbot renew --quiet

🔍 憑證類型

1. DV(Domain Validation)

DV = 域名驗證憑證

驗證內容:
- 只驗證域名擁有權
- 不驗證組織身份

申請時間:
- 幾分鐘到幾小時(自動化)

價格:
- 免費(Let's Encrypt)
- 或 $10-$50/年

適用:
- 個人網站
- 部落格
- 小型企業網站

瀏覽器顯示:
🔒 example.com

範例:
- Let's Encrypt
- Cloudflare SSL

2. OV(Organization Validation)

OV = 組織驗證憑證

驗證內容:
- 驗證域名擁有權 ✅
- 驗證組織存在性 ✅
- 驗證組織法律地位 ✅

申請時間:
- 1-3 天(人工審核)

價格:
- $50-$200/年

適用:
- 企業網站
- 電商網站

瀏覽器顯示:
🔒 example.com
點擊可看到組織資訊:
Example Inc., Taiwan

範例:
- DigiCert OV
- GlobalSign OV

3. EV(Extended Validation)

EV = 擴展驗證憑證

驗證內容:
- 驗證域名擁有權 ✅
- 驗證組織存在性 ✅
- 驗證組織法律地位 ✅
- 驗證組織運營狀態 ✅
- 驗證組織實體地址 ✅
- 電話驗證 ✅

申請時間:
- 3-7 天(嚴格審核)

價格:
- $200-$500+/年

適用:
- 金融機構
- 大型電商
- 高安全需求網站

瀏覽器顯示(舊版):
🔒 Example Inc. [TW] | example.com
(綠色網址列,已移除)

瀏覽器顯示(現在):
🔒 example.com
點擊可看到完整組織資訊

範例:
- DigiCert EV
- GlobalSign EV

注意:
Chrome 從 2019 年移除 EV 的特殊顯示
現在顯示方式與 DV/OV 相同

4. 萬用憑證(Wildcard Certificate)

萬用憑證 = 覆蓋所有子域名

範例:
*.example.com

涵蓋:
✅ www.example.com
✅ blog.example.com
✅ api.example.com
✅ shop.example.com

不涵蓋:
❌ example.com(主域名)
❌ sub.api.example.com(多層子域名)

申請:
openssl req -new -key private.key -out request.csr
Common Name: *.example.com

Let's Encrypt 支援:
certbot certonly --manual -d *.example.com \
  --preferred-challenges dns

需要 DNS 驗證(不支援 HTTP 驗證)

價格:
- Let's Encrypt:免費
- 商業 CA:$100-$300/年

⚠️ 憑證問題與解決

1. 憑證過期

問題:
憑證有效期過了

瀏覽器警告:
⚠️ NET::ERR_CERT_DATE_INVALID
您的連線不是私人連線

原因:
- 忘記更新憑證
- Let's Encrypt 90 天過期

解決:
1. 檢查憑證有效期
   openssl x509 -in certificate.crt -noout -dates

   notBefore=Jan  1 00:00:00 2024 GMT
   notAfter=Jan  1 23:59:59 2025 GMT ← 已過期

2. 更新憑證
   # Let's Encrypt
   sudo certbot renew

   # 商業 CA
   重新申請憑證

3. 設定自動更新
   # Cron job
   0 0 1 * * certbot renew --quiet

2. 憑證域名不符

問題:
憑證的域名與實際域名不符

瀏覽器警告:
⚠️ NET::ERR_CERT_COMMON_NAME_INVALID
此伺服器無法證明它是 example.com

原因:
- 憑證是給 www.example.com
- 但訪問 example.com

範例:
憑證:CN=www.example.com
訪問:https://example.com
→ 域名不符 ❌

解決:
1. 申請包含兩個域名的憑證
   SAN(Subject Alternative Name):
   - www.example.com
   - example.com

2. 重新導向
   http://example.com → https://www.example.com

3. 使用萬用憑證
   *.example.com(但不包含主域名)

3. 缺少中繼憑證

問題:
伺服器只提供網站憑證,沒有提供中繼 CA 憑證

瀏覽器警告:
⚠️ NET::ERR_CERT_AUTHORITY_INVALID
無法驗證憑證鏈

原因:
信任鏈不完整:
網站憑證(example.com)
    ↓ 由誰簽發?
中繼 CA 憑證(缺少)❌
    ↓
根 CA(瀏覽器內建)

解決:
1. 檢查憑證鏈
   openssl s_client -connect example.com:443 \
     -showcerts

2. 合併憑證
   cat certificate.crt intermediate.crt > fullchain.crt

3. Nginx 設定
   ssl_certificate /path/to/fullchain.crt;
   ssl_certificate_key /path/to/privkey.key;

4. 重啟伺服器
   sudo systemctl restart nginx

4. 自簽憑證

問題:
使用自己簽發的憑證(不透過 CA)

瀏覽器警告:
⚠️ NET::ERR_CERT_AUTHORITY_INVALID
此伺服器無法證明它的身份

原因:
- 憑證不是由可信任的 CA 簽發
- 開發測試使用

產生自簽憑證:
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout key.pem -out cert.pem -days 365

瀏覽器:
CA:Unknown ❌
→ 不信任

使用場景:
✅ 本地開發(localhost)
✅ 內部測試
❌ 正式環境(絕對不要用)

解決:
正式環境使用真正的 CA 憑證
- Let's Encrypt(免費)
- 商業 CA

5. 混合內容(Mixed Content)

問題:
HTTPS 頁面載入 HTTP 資源

警告:
Mixed Content: The page at 'https://example.com'
was loaded over HTTPS, but requested an insecure resource.

範例:
<!-- HTTPS 頁面 -->
<html>
<img src="http://example.com/image.jpg">  ← HTTP ❌
<script src="http://example.com/script.js"></script>  ← HTTP ❌
</html>

瀏覽器行為:
- 被動內容(圖片、影片):顯示警告 ⚠️
- 主動內容(JavaScript、CSS):阻擋 ❌

解決:
1. 全部改用 HTTPS
   <img src="https://example.com/image.jpg">

2. 使用協定相對 URL
   <img src="//example.com/image.jpg">
   (自動使用當前頁面的協定)

3. 檢查工具
   - Chrome DevTools → Console
   - 查看 Mixed Content 警告

🎓 面試常見問題

Q1:數位憑證包含哪些資訊?

A:網域名稱、公鑰、有效期、發行者、數位簽章

主要欄位:

1. 主體(Subject)
   - CN(Common Name):www.example.com
   - O(Organization):Example Inc.
   - C(Country):TW

2. 發行者(Issuer)
   - CN:Let's Encrypt Authority X3
   - O:Let's Encrypt

3. 有效期(Validity)
   - Not Before:2024-01-01
   - Not After:2025-01-01

4. 公鑰(Public Key)
   - Algorithm:RSA 2048-bit
   - Public Key:[key data]

5. 序號(Serial Number)
   - 唯一識別碼

6. 簽章演算法(Signature Algorithm)
   - sha256WithRSAEncryption

7. 擴充欄位(Extensions)
   - SAN:www.example.com, example.com
   - Key Usage:Digital Signature, Key Encipherment
   - Extended Key Usage:TLS Web Server Authentication

8. CA 數位簽章
   - CA 用私鑰簽署整個憑證
   - 防止偽造

關鍵:
憑證本身是公開的(不含私鑰)
私鑰永遠保密存放在伺服器上

Q2:CA 如何驗證網域擁有權?

A:三種主要方式

1. HTTP 檔案驗證(HTTP-01)
CA:請在你的網站放置特定檔案
    http://example.com/.well-known/acme-challenge/TOKEN

你:上傳檔案到伺服器
    /var/www/html/.well-known/acme-challenge/TOKEN

CA:訪問檔案
    curl http://example.com/.well-known/acme-challenge/TOKEN
    → 如果能訪問且內容正確 ✅

優點:
✅ 簡單、自動化
✅ Let's Encrypt 常用

缺點:
❌ 需要 Web 伺服器運行
❌ 不支援萬用憑證

2. DNS TXT 記錄驗證(DNS-01)
CA:請新增 DNS TXT 記錄
    _acme-challenge.example.com TXT "TOKEN_VALUE"

你:新增 DNS 記錄
    @ DNS 服務商(Cloudflare、Route53)

CA:查詢 DNS
    dig _acme-challenge.example.com TXT
    → 如果記錄存在且值正確 ✅

優點:
✅ 支援萬用憑證(*.example.com)
✅ 不需要 Web 伺服器

缺點:
❌ 需要 DNS API 存取
❌ 較複雜

3. Email 驗證
CA:發送驗證郵件到
    admin@example.com
    webmaster@example.com
    postmaster@example.com

你:收到郵件,點擊驗證連結

CA:確認點擊 ✅

優點:
✅ 簡單

缺點:
❌ 需要能接收該網域的郵件
❌ 較慢(人工操作)
❌ 較不安全

Q3:為什麼瀏覽器信任 CA?

A:瀏覽器內建根 CA 清單

信任機制:

1. 瀏覽器預先內建根 CA
Chrome/Firefox/Safari 內建:
├─ DigiCert Global Root CA
├─ Let's Encrypt ISRG Root X1
├─ GlobalSign Root CA
├─ GeoTrust Global CA
└─ 約 50-100 個根 CA

2. 作業系統信任清單
Windows:憑證存放區
macOS:鑰匙圈
Linux:/etc/ssl/certs/

3. 驗證流程
網站 → 瀏覽器:這是我的憑證 📜
瀏覽器:
├─ 誰簽發的?→ Let's Encrypt
├─ Let's Encrypt 在信任清單中嗎?✅
├─ 驗證 Let's Encrypt 的簽章 ✅
└─ 信任這個憑證 ✅

4. 信任鏈
瀏覽器信任根 CA
→ 根 CA 簽發中繼 CA
→ 中繼 CA 簽發網站憑證
→ 瀏覽器信任網站憑證

5. CA 如何進入信任清單?
- 嚴格的審核程序
- 必須遵守 CA/Browser Forum 規範
- 定期審計
- 可以被移除(如果違規)

歷史案例:
2016 年:WoSign 被 Chrome/Firefox 移除信任
原因:簽發假憑證、不當行為

結論:
瀏覽器信任 CA = CA 經過嚴格審查 + 持續監督

Q4:憑證過期會怎樣?

A:瀏覽器警告,用戶無法訪問

過期後的影響:

1. 瀏覽器警告
Chrome:
⚠️ 您的連線不是私人連線
NET::ERR_CERT_DATE_INVALID

您嘗試存取的網站憑證已過期
攻擊者可能正試圖竊取您的資訊

[返回安全頁面]  [進階設定]

2. 用戶反應
大多數用戶:
- 看到警告就離開
- 不會繼續訪問
- 信任度大幅下降

技術用戶:
- 可能點「進階設定」→「繼續前往」
- 但仍有風險警告

3. SEO 影響
Google:
- 憑證過期會影響排名
- 可能被標記為不安全網站

4. 功能影響
API:
- 大多數 HTTP 客戶端拒絕連線
- curl、requests 等工具報錯

行動應用:
- iOS/Android 預設拒絕過期憑證

5. 商業影響
- 失去客戶信任
- 交易量下降
- 品牌形象受損

Let's Encrypt 特別注意:
- 90 天過期(而不是 1-2 年)
- 必須設定自動更新
- 否則很容易過期

預防措施:
1. 設定憑證過期提醒
   - Email 通知
   - 監控系統

2. 自動更新(Let's Encrypt)
   certbot renew --quiet
   設定 cron job

3. 監控服務
   - SSL Labs
   - UptimeRobot
   - 在過期前 30/15/7 天提醒

Q5:自簽憑證和 CA 憑證有什麼差異?

A:信任來源不同

自簽憑證(Self-Signed Certificate):

產生方式:
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout key.pem -out cert.pem -days 365

特性:
- 自己簽發自己(沒有第三方)
- 瀏覽器不信任 ❌
- 免費 ✅

驗證流程:
網站:這是我的憑證,我自己簽發的
瀏覽器:誰證明你是你?
網站:我自己!
瀏覽器:不可信 ❌

警告:
⚠️ NET::ERR_CERT_AUTHORITY_INVALID

使用場景:
✅ 本地開發(localhost)
✅ 內部測試環境
✅ 學習和實驗
❌ 正式環境(絕對不可)

CA 憑證:

產生方式:
1. 產生 CSR
2. 提交給 CA
3. CA 驗證身份
4. CA 簽發憑證

特性:
- 第三方(CA)簽發
- 瀏覽器信任 ✅
- 需要費用(或免費如 Let's Encrypt)

驗證流程:
網站:這是我的憑證,Let's Encrypt 簽發的
瀏覽器:檢查 Let's Encrypt 的簽章...✅
瀏覽器:Let's Encrypt 在信任清單中 ✅
瀏覽器:信任這個網站 ✅

顯示:
🔒 安全

使用場景:
✅ 所有正式環境
✅ 面向公眾的網站
✅ 需要用戶信任

對比總結:
自簽憑證 = 自己說「我是我」
CA 憑證 = 政府證明「他是他」

就像:
自簽 = 拿自己寫的身份證
CA = 拿政府發的身份證

結論:
正式環境必須使用 CA 憑證
現在 Let's Encrypt 免費,沒理由用自簽憑證

✅ 重點回顧

數位憑證:

  • 網站的「數位身份證」
  • 證明網站身份的真實性
  • 由 CA 簽發和驗證

憑證內容:

  • 網域名稱、公鑰、有效期
  • 發行者、數位簽章
  • 擴充欄位(SAN、Key Usage)

CA 的角色:

  • 數位世界的「公證人」
  • 驗證網域擁有權
  • 簽發和管理憑證

信任鏈:

瀏覽器內建根 CA
    ↓ 信任
根 CA 憑證
    ↓ 簽發
中繼 CA 憑證
    ↓ 簽發
網站憑證

憑證類型:

  • DV:只驗證域名(快速、便宜)
  • OV:驗證組織(中等審核)
  • EV:擴展驗證(嚴格審核、最安全)
  • 萬用憑證:涵蓋所有子域名

Let’s Encrypt:

  • 免費、自動化的 CA
  • 90 天有效期
  • 使用 Certbot 自動申請和更新

常見問題:

  • 憑證過期 → 設定自動更新
  • 域名不符 → 使用 SAN 或萬用憑證
  • 缺少中繼憑證 → 使用 fullchain.crt
  • 自簽憑證 → 正式環境不可用

面試重點:

  • ✅ 數位憑證的結構和內容
  • ✅ CA 的三種驗證方式
  • ✅ 瀏覽器如何信任 CA
  • ✅ 憑證過期的影響
  • ✅ 自簽憑證 vs CA 憑證

上一篇: 03-2. SSL/TLS 加密原理 下一篇: 03-4. HTTPS 握手過程


最後更新:2025-01-06

0%