iT邦幫忙

0

https 加密公鑰疑問

  • 分享至 

  • xImage

大家好:
最近在弄 https 憑證,於是回頭複習了 https 原理,參考以下網址

https://dywang.csie.cyut.edu.tw/dywang/rhce7/node77.html
https://www.readfog.com/a/1638923950567297024

https
一般在配置 Nginx 的 SSL 設定的時候,只會拿到 crt 與 自己產生的 key/pem 進行配置。
不太懂的地方是圖片 4、5、6、7 這一段。

瀏覽器從 Server 拿到 cert 的時候,有一個公開鑰匙是同時與憑證送過來的。
Q: 這個公鑰是 Server的,還是 ca 的公鑰?
因為從產生憑證,我只記得產生了自己的私鑰,CSR,不太記得有自己的公鑰這隻檔案。
如果是有一把 Server 公鑰伴隨 crt 給 client,生成隨機數後回給 server,再用server 私鑰解開,這樣的話,我想知道公鑰是放在哪邊。

如果這個是 ca 的公鑰的話,生成隨機數用 ca 公鑰加密後給到 server,server 上也沒有 ca 的私鑰,我收到的只有 crt 這個檔案,是怎麼解開的呢?

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

7
黃彥儒
iT邦高手 1 級 ‧ 2023-09-10 19:15:36
最佳解答

公鑰是伺服器的,在生產CSR時,是生成伺服器私鑰與其公鑰,公鑰給CA,CA用他自己的私鑰對其背書並返回背書完的證書。
4 是給客戶端背書完的證書(含以CA私鑰簽署的Server公鑰),客戶端一般內建可信CA證書庫,所以他可以去驗證這個伺服器證書是否由可信CA背書。
後續加密是以伺服器公鑰為準,CA也無法解密(因為CSR不含私鑰)

關於樓主提出的openssl genrsa -out key.pem指令實際上會產生一個金鑰對,key.pem包含公鑰與私鑰的部分;RAS算法需要三個數,N, e, d,公鑰含有(N, e) ,私鑰含有(N, d)。
可以使用 openssl rsa -in key.pem -pubout > mykey.pub 單獨匯出公鑰。


在這條線上,你僅是生成了一組 RAS 金鑰對,他們和 SSL/TLS 還沒關係,在產生CSR時,他需要一個非對稱加密法 (RSA、ECC或其他加密算法),所以你使用了openssl req 來生成一個PCKS#10格式的CSR,它包含了三個主要部分:認證請求資訊、簽章算法和認證請求資訊上的數位簽章,而公鑰是認證請求資訊的一部分。

CA收到CSR後會依此發放伺服器憑證,因為CSR沒有伺服器私鑰,所以經該證書加密的流量CA也無法解密(其實現在他只用來加密一組對稱金鑰{看起來是7的部分},且用Diffie-Hellman key exchange做前向保護{你的圖裡面似乎沒有})。


作為證明,我先用openssl genrsa -out testkey.pem 2048產生了一個金鑰叫testkey.pem,用openssl rsa -in testkey.pem -text -noout可以看到

modulus:
    00:b3:c1:6c:41:a8:a5:4b:44:c8:dc:da:a1:a9:8d:
    34:94:a2:b4:fe:36:ff:96:fb:c0:8d:cf:92:ac:3b:
    ca:c5:6e:82:4a:0d:66:d8:b3:48:dc:9a:9a:b1:4e:
    fd:e4:eb:06:81:fd:8b:a2:73:06:32:77:ce:e2:8f:
    6d:d2:18:18:d0:6b:6a:88:a9:cf:f5:f2:a3:08:72:
    55:5c:ae:4e:5b:24:5f:4e:62:dc:69:8f:10:6a:77:
    27:5d:97:4b:05:aa:b6:5c:d9:0b:ee:31:1c:5e:23:
    2f:9c:8c:60:82:01:c1:f7:68:86:2c:0f:86:2a:aa:
    92:9f:a4:76:f1:cb:39:ae:c5:ec:ae:66:78:94:c1:
    5d:16:b9:de:89:73:3b:61:2c:27:df:c8:0f:d8:82:
    1a:36:94:91:ef:8f:5c:51:f5:f2:22:9c:ce:3a:a9:
    9b:97:36:ce:73:d0:01:81:e5:cf:1a:61:5d:2e:67:
    65:da:e1:54:f4:87:dd:24:d4:61:cb:aa:3a:c3:40:
    d7:e0:6d:b7:c9:60:46:a4:2b:69:e2:93:97:0c:f5:
    17:c6:e4:e1:1f:75:3d:2f:0f:b0:07:f5:b1:14:3f:
    a7:84:92:c2:87:a2:91:fb:09:03:08:68:54:30:ea:
    1c:22:6e:3f:1e:5e:fc:5b:e0:a2:5b:15:99:85:d8:
    5a:4d
publicExponent: 65537 (0x10001)
privateExponent:
    13:77:c0:8b:78:e2:13:fd:8a:5a:7e:f4:30:ba:7a:
    06:19:fc:0b:a7:35:b5:aa:a4:cf:46:fa:8d:dc:38:
    e8:fa:7f:b2:58:f2:b9:47:eb:7d:76:e2:07:8f:74:
    48:69:5a:ce:53:c1:1e:72:22:2a:ef:96:50:ab:b3:
    7b:64:40:35:bc:58:70:9e:21:87:73:c4:8b:ea:e4:
    0b:52:56:6a:a1:0d:10:5e:7d:1c:12:92:36:d1:9a:
    4a:14:d3:5b:75:02:64:9a:5e:24:29:1d:f7:25:0c:
    e8:41:bc:c6:ff:bd:3b:d8:0e:65:f1:b5:78:63:fa:
    56:bf:57:61:76:fe:d3:8a:6d:fa:6f:ed:e4:18:a2:
    fe:0f:8b:0b:2e:a6:b6:ff:dd:5c:53:07:89:1c:8b:
    7c:33:a5:1a:02:2e:f1:ad:96:9f:98:83:a4:0f:39:
    04:0e:0d:27:87:6f:e1:89:57:21:3f:4d:f0:b4:41:
    3a:85:05:47:68:f1:d7:7a:52:15:4b:78:bc:59:62:
    6c:34:0e:99:ec:66:d9:f0:cc:91:84:23:37:e5:3c:
    6f:57:40:ab:ad:3d:eb:f0:97:b7:9c:96:3a:ae:49:
    03:c4:ec:19:cf:52:55:64:4c:34:cb:ad:35:10:ab:
    80:df:f2:db:51:3a:1f:92:08:8e:75:f3:de:df:f9:
    d9

分別是維基百科提到的 N(modulus),e(publicExponent),d(privateExponent)三項要素; (N, e)就是公鑰、(N, d)就是私鑰。

看更多先前的回應...收起先前的回應...

那請問 Server 公鑰在哪邊呢?
https://aimuke.github.io/others/2020/03/27/https-certificate/

1.生成服务端私钥(可以给商户客户)
openssl genrsa -out private/server-key.pem 2048 這個是私鑰
2.生成证书请求文件
openssl req -new -key private/server-key.pem -out private/server.csr -subj "/C=CN/ST=ShangHai/L=ShangHai/O=Yunan International Trust Company/OU=Internet Finance/CN=YNTRUST"

到這一步,我都不知道公鑰在哪邊,看起來我只有生成私鑰而已。

含以CA私鑰簽署的Server公鑰 <--- 這個意思是 CA私鑰 = Server公鑰?

黃彥儒 iT邦高手 1 級 ‧ 2023-09-10 19:43:35 檢舉

证书请求文件有阿

疑? CSR 輸入的 key 不是私鑰嗎?
openssl req -new "-key private/server-key.pem"
-out private/server.csr -subj "/C=CN/ST=ShangHai/L=ShangHai/O=Yunan International Trust Company/OU=Internet Finance/CN=YNTRUST"

黃彥儒 iT邦高手 1 級 ‧ 2023-09-10 19:51:01 檢舉

用私鑰不就可以算出公鑰了?(錯誤,做不到)
CSR輸入的是金鑰對,但私鑰並不含在CSR內

黃彥儒 iT邦高手 1 級 ‧ 2023-09-10 19:53:14 檢舉

(錯誤資訊,自刪)

OAO,我好像有點理解了... private/server-key.pem 這個內容長這樣,..
-----BEGIN RSA PRIVATE KEY-----
我是KEY
-----END RSA PRIVATE KEY-----

openssl rsa -in server-key.pem -pubout -outform PEM -out server-key-pub.pem

cat server-key-pub.pem
-----BEGIN PUBLIC KEY-----
我是公鑰
-----END PUBLIC KEY-----

所以..原本的private/server-key.pem其實是公鑰跟私鑰都在裡面,
只是打開只看到PRIVATE KEY內容..。

黃彥儒 iT邦高手 1 級 ‧ 2023-09-10 20:29:55 檢舉

我更新了一些東西,剛剛講錯了一些,你更新一下

謝謝你,所以結論是
cat key.pem 開起來顯示是 PRIVATE KEY,其實金鑰對(公私鑰一體)
CSR 雖然 -in key.pem,但是包在裡面的是伺服器公鑰
CRT 是用ca用自己ca的根憑證(或中繼憑證)+ca的私鑰產出來的產物,
內容物其實是 網域的憑證+伺服器公鑰+ca的東西(我不知道,可能是名子如 let's encrypt?),這個 ca的東西,瀏覽器之所以信任憑證,是因為電腦內有信任的清單,然後就瀏覽就打開這一包東西,把伺服器公鑰拿出來對瀏覽器產生的亂數加密,然後給到伺服器之後,由伺服器的私鑰解開。

黃彥儒 iT邦高手 1 級 ‧ 2023-09-10 22:05:20 檢舉

其實 x509證書的內容在這裡: https://zh.wikipedia.org/zh-tw/X.509

好的,非常謝謝您。

froce iT邦大師 1 級 ‧ 2023-09-11 09:50:40 檢舉

cat key.pem 開起來顯示是 PRIVATE KEY,其實金鑰對(公私鑰一體)

不是,如果你是在linux下,通常產生的公私鑰對都是分開來的,習慣上私鑰會給個附檔名.key.pem或.key,公鑰附檔名會給.crt。但實際上都是pem格式。
這個你自己去看nginx或apache的設定就可以知道了。

# NGINX的設定檔範例
# 公
ssl_certificate /etc/ssl/bundle.crt;
# 私
ssl_certificate_key /etc/ssl/yourdomain.key;

如果你是申請SSL憑證的話流程是這樣。
https://blog.miniasp.com/post/2019/04/17/Convert-PFX-and-CER-format-using-OpenSSL

自簽憑證的話是這樣:
https://blog.miniasp.com/post/2019/02/25/Creating-Self-signed-Certificate-using-OpenSSL

可以看到pem格式公私鑰對都是分開的。

windows/IIS則是會把兩個包起來,再進行一次對稱加密(所以你得保存好當時的密碼),存在本機儲存區。用的是.pfx格式。

黃彥儒 iT邦高手 1 級 ‧ 2023-09-11 14:14:14 檢舉

froce 大,我這邊測試了一下,用openssl genrsa -out testkey.pem 2048產出來的,是包含RSA中所需要的三個數(N, e, d)的,可以用openssl rsa -in testkey.pem -text -noout去讀取這三個數

froce iT邦大師 1 級 ‧ 2023-09-11 21:24:57 檢舉

https://www.openssl.org/docs/man1.0.2/man1/genrsa.html
genrsa - generate an RSA private key
genrsa這指令很明確沒提到金鑰對

我猜e的部分是你過rsa這個副指令時產出的。
https://www.openssl.org/docs/man1.0.2/man1/rsa.html
The rsa command processes RSA keys.
-text 參數: prints out the various public or private key components in plain text in addition to the encoded version.

要從私鑰產生公鑰也是要靠rsa這指令。
openssl rsa -in privatekey.pem -out publickey.pem -pubout -outform PEM

不過我前面提到的crt是公鑰算是有點錯誤的,crt應該是證書,是公鑰和CSR發給簽屬機構,用他的私鑰去簽屬,也就是憑證(crt)是 網域資訊+公鑰 給簽證公司的私鑰加密的結果,所以還會附憑證公司的憑證,這樣才會形成證書的信任鍊。

有興趣做做自簽CA的話可以參考下面這篇,會對整個流程有點初步的認識:
https://weirenxue.github.io/2021/06/15/ssl_self_sign/

但他的指令我記得有點錯誤,不是完全正確


後來想了一下,私鑰沒有經過選定e的過程也產生不出來,我猜openssl上定義私鑰的定義應該是只要有N和d就認為是私鑰,多出e沒關係。只有N和e就是公鑰,這樣其實也蠻合理的。所以說genrsa產生的是鍵對應該也沒錯。

黃彥儒 iT邦高手 1 級 ‧ 2023-09-11 23:10:53 檢舉

e好像有說法是3或是65537,數學上我是還沒搞懂為什麼要這樣選

黃彥儒 iT邦高手 1 級 ‧ 2023-09-12 14:08:14 檢舉

froce 大,是不是e實際上沒有太大的意義,我查了一下資料,大多都說使用3, 17, 65537,是基於旁路攻擊防禦與計算效率的考量,如果大家都用一樣,那似乎沒有必要特別記錄下來?

froce iT邦大師 1 級 ‧ 2023-09-12 15:06:29 檢舉

openssl有參數可以讓你選,所以還是得記比較方便吧,總不能這三個都試,而且能用的不是只有這三個,你也不能只認定所有人只用這三個,搞不好就有人想用65537以上的。
另外65537看文章是說這是最能符合複雜度和性能的平衡,其他的複雜度太低。
https://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537

pcfix905 iT邦新手 5 級 ‧ 2023-09-27 15:45:15 檢舉

謝謝分享!

也歡迎逛逛我的網站:
https://hk-computer-repair.com/

我要發表回答

立即登入回答