
我使用 curve 使用 libressl 3.0 產生了私鑰secp521r1
。
openssl genpkey -aes128 -algorithm EC -pkeyopt ec_paramgen_curve:secp521r1 -pkeyopt ec_param_enc:named_curve
據我所知,這條曲線與 ssh-keygen 使用的曲線相同ssh-keygen -t ecdsa -b 521
,並且從文檔中我知道 ssh-keygen 現在使用 aes128 來加密私鑰。
libressl 私鑰的大小為534
,ssh-keygen 私鑰的大小為736
。
我的問題是: ssh-keygen 做了什麼額外的事情來增加金鑰的大小?
另:兩者可以互換嗎?一個私鑰產生的私鑰可以轉換成另一個私鑰嗎?
答案1
TLDR:私鑰檔案有許多不同的格式
這部分取決於您沒有提供的 OpenSSH 版本。
從歷史上看,除了早已過時的協定版本1(以及金鑰類型「rsa1」)之外,OpenSSH 使用OpenSSL(的libcrypto 部分)來執行大部分加密操作——包括在檔案中儲存私鑰(或實際上的密鑰對),使用這SSLeay/OpenSSL 定義的「傳統」或「遺留」格式。 OpenSSL 還支援「新」(大約從 1998 年開始!)PKCS8 格式,這些格式(在某種程度上)更安全。因此,OpenSSL 支援「ECDSA」的 4 種 PEM 格式(更準確地說是 X9 風格的 Weierstrass EC,涵蓋 X9.62 ECDSA 和 X9.63 ECDH),其中 OpenSSH產生只有 2 個,但(使用 libcrypto)可以讀取全部。ssh-keygen
加密時OpenSSL 格式文件中,最新版本確實使用 AES-128-CBC,但這並不總是如此。
從 2014-01 發布 6.5 開始,OpenSSH 新增了自己的「新」檔案格式,部分是為了提供比 OpenSSL 舊格式(加密時)更好的安全性,部分是為了支援當時的新演算法 Ed25519,而 OpenSSL 當時根本不支援該演算法。ssh-keygen
可以選擇-o
為 ed25519(或 rsa1)以外的任何金鑰類型請求新格式,並且您會發現過去幾年中許多 Stack Q 和 As 引用並通常推薦此選項。預設情況下,「新」格式檔案使用 AES256-CBC 加密,可以使用 覆蓋-Z ciphername
,但手冊頁顯然尚未更新其中任何一個。從 2018-08 版本 7.8 開始,OpenSSH 現在預設為所有金鑰類型使用「新」格式,儘管您可以使用-m pem
ed25519 以外的任何格式來要求 OpenSSL 格式。如果您檢查man ssh-keygen
您的系統(除非是 Windows),它應該描述其中一種情況,很可能是後者。
(還有 PKCS12 又稱 PFX 格式,OpenSSL能用於私鑰,但通常僅用於將一個(或多個)私鑰與該金鑰的一個或多個 X.509 憑證組合在一起,這是一種不同的情況,不適用於 SSH,它從不使用X.509 憑證。其他程式或系統使用其他格式:「商業」/Tectia SSH 有自己的格式,PuTTY 有自己的格式 PPK = PuTTY 私鑰。等等,等等,尤爾·伯連納。所有這些在語義上都是等效的,並且只要有合適的工具就可以相互轉換。
OpenSSH 使用的所有私鑰格式都是PEM型;二進位資料以 base64 形式編碼為文本,標題和尾部行的格式如下
-----BEGIN (something)-----
(sometimes some headers here)
(data encoded in base64, broken into lines of 64 characters)
-----END (something)-----
所以你只需查看破折號-BEGIN 行就可以知道你有哪種格式。查看近交叉複製https://security.stackexchange.com/questions/39279/stronger-encryption-for-ssh-keys或者更簡單地說https://security.stackexchange.com/questions/129724/how-to-check-if-an-ssh-private-key-has-passphrase-or-not和https://security.stackexchange.com/questions/200935/how-do-i-define-if-an-existing-ssh-private-key-is-secure(礦)。
差異:ecdsa-p521 金鑰的 736 個字元大小與 OpenSSH 新格式匹配未加密的- 你是當然你給了它一個密碼? -- 並且 534 與 OpenSSL 1.0.2 創建的 PKCS8 加密格式匹配,IIRC 是 LibreSSL 分叉時的格式。 (OpenSSL 1.1.0 版本將 PKCS8 加密更改為在 PBKDF2 中使用 HMAC-SHA256,這使得檔案稍大。OpenSSL 1.1.0 版本也使 param_enc=named 成為預設值,因此您不再需要指定它。)格式比 版本還使 param_enc=named 成為預設值,因此您不再需要指定它。)格式比PKCS8-enc 格式大,主要是因為,沒有明顯的原因,它儲存公鑰值(對於ECDSA,X9.62 格式的曲線點)兩次-- 一旦進入為公鑰指定的文件部分,並且再次在為私鑰指定的部分。此外,OpenSSH 格式的大部分元資料都是文字字串,所有長度欄位都是4 個位元組,而PKCS8(如OpenSSL 傳統格式)使用ASN.1,可變長度長度欄位大多只有1 個位元組,元數據大多是二進制,尤其是所用演算法的“OID”。
另:兩者可以互換嗎?一個私鑰產生的私鑰可以轉換成另一個私鑰嗎?
是和不是。如前所述,使用 OpenSSL 的 OpenSSH 可以讀取(但不能寫入)PKCS8,因此ssh-keygen
可以透過對其進行空更改將其轉換為 OpenSSH-new,即將密碼「更改」為現有值;從 6.5 到 7.7,您必須指定-o
,從 7.8 開始,它是預設值。另一方面,ssh-keygen
可以轉換為 OpenSSL-legacy,但不能直接轉換為 PKCS8,您需要使用openssl
來執行此操作,無論是在 1.0.0 版本中明確使用pkcs8 -topk8
或在1.0.0 版本中(現在應該是每個人,而且絕對是所有LibreSSL)pkey
。 (前者預設為加密,後者預設為未加密,但兩者都可以被覆蓋。)