ssh-keygen の秘密鍵と libressl の秘密鍵の違いは何ですか?

ssh-keygen の秘密鍵と libressl の秘密鍵の違いは何ですか?

libressl 3.0 と curve を使用して秘密鍵を生成しました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」(より正確には、X9.62 ECDSA と X9.63 ECDH の両方をカバーする X9 スタイルの Weierstrass EC) 用に 4 つの PEM 形式がサポートされていますが、そのうち OpenSSH では生成する2つだけですが(libcryptoを使用)すべてを読み取ることができます。ssh-keygen暗号化するとOpenSSL形式ファイルでは、最近のバージョンでは AES-128-CBC が使用されていますが、これは常に当てはまるわけではありません。

2014年1月のリリース6.5から、OpenSSHは独自の「新しい」ファイル形式を追加しましたは、OpenSSL のレガシー形式 (暗号化時) よりも優れたセキュリティを提供するためと、当時 OpenSSL がまったくサポートしていなかった当時の新しいアルゴリズム Ed25519 をサポートするためでした。 には、 ed25519 (または rsa1) 以外のキータイプに対して新しい形式を要求するssh-keygenオプションがあり-o、過去数年間の多くの Stack Q と A でこのオプションが参照され、通常は推奨されています。 「新しい」形式のファイルは、デフォルトで AES256-CBC で暗号化されますが、 を使用して上書きできます-Z ciphernameが、man ページはどちらについても更新されていないようです。2018-08 のリリース 7.8 以降、OpenSSH はすべてのキータイプに対してデフォルトで「新しい」形式を使用するようになりましたが、 を使用して-m pemed25519 以外のものに対して OpenSSL 形式を要求することもできます。man ssh-keygenシステムを確認すると (Windows でない限り)、これらのいずれかのケース (おそらく後者) が説明されているはずです。

(PKCS12、別名PFX形式もあり、OpenSSLできる秘密鍵に使用しますが、通常は、秘密鍵 (または複数の鍵) をその鍵の 1 つ以上の X.509 証明書と組み合わせる場合にのみ使用されます。これは別の状況であり、X.509 証明書を使用しない SSH には適用されません。他のプログラムまたはシステムでは、他の形式が使用されます。「商用」/Tectia SSH には独自の形式があり、PuTTY には独自の形式 PPK = PuTTY 秘密鍵があります。などなど、Yul Brynner。これらはすべて意味的に同等であり、適切なツールがあれば相互変換できます。

OpenSSHで使用されるすべての秘密鍵形式はPEMスタイル; バイナリデータは、ヘッダーとトレーラーの行を含むbase64形式でテキストにエンコードされます。

-----BEGIN (something)-----
(sometimes some headers here)
(data encoded in base64, broken into lines of 64 characters)
-----END (something)-----

ダッシュ-BEGIN行を見るだけで、どのフォーマットであるかがわかります。near-crossdupesを参照してください。https://security.stackexchange.com/questions/39279/sshキーの暗号化の強化またはもっと簡単にhttps://security.stackexchange.com/questions/129724/ssh プライベートキーにパスフレーズがあるかどうかを確認する方法そしてhttps://security.stackexchange.com/questions/200935/how-do-i-determine-if-an-existing-ssh-private-key-is-secure(私の)。

違い:ecdsa-p521 キーの 736 文字のサイズは OpenSSH の新しい形式と一致します。暗号化されていない- あなたはもちろんパスフレーズを与えましたか? -- 534 は OpenSSL 1.0.2 で作成された PKCS8 暗号化形式と一致します。これは、LibreSSL がフォークされたときのことです。(OpenSSL 1.1.0 以上では、PKCS8 暗号化が PBKDF2 の HMAC-SHA256 を使用するように変更され、ファイルがわずかに大きくなります。また、OpenSSL 1.1.0 以上では param_enc=named がデフォルトになったため、指定する必要がなくなりました。) OpenSSH の新しい形式は、PKCS8-enc 形式よりも大きくなっていますが、その理由は明らかではありません。公開鍵の値 (ECDSA の場合は X9.62 形式の曲線ポイント) を格納するためです。2回-- ファイルの公開鍵に指定されたセクションに1回、また秘密鍵に指定されたセクションにあります。さらに、OpenSSH 形式ではメタデータのほとんどがテキスト文字列で、すべての長さフィールドは 4 バイトですが、PKCS8 (OpenSSL の従来の形式と同様に) は ASN.1 を使用し、可変長の長さフィールドはほとんどが 1 バイトで、メタデータはほとんどがバイナリです (特に、使用されるアルゴリズムの「OID」)。

また、両方とも交換可能ですか? 一方に生成された秘密鍵を他方に変換できますか?

はい、そしていいえです。前述のように、OpenSSL を使用する OpenSSH は PKCS8 を読み取ることができます (ただし、書き込みはできません)。そのため、ssh-keygennull の変更 (つまり、パスワードを既存の値に「変更」) を行うことで、OpenSSH-new に変換できます。6.5 から 7.7 では指定する必要があり-o、7.8 以上ではこれがデフォルトです。逆に、ssh-keygenOpenSSL-legacy に変換できますが、PKCS8 に直接変換することはできません。opensslこれを行うには、明示的に を使用するpkcs8 -topk8か、1.0.0 以上 (これで、すべてのユーザー、特にすべての LibreSSL が対象) ではを使用する必要がありますpkey。(前者はデフォルトで暗号化され、後者は暗号化されませんが、どちらも上書きできます。)

関連情報