本文へスキップ
ecdsa.com
コマンドライン

OpenSSH (ssh-keygen)

OpenSSH 10 は SSH のツール群で、付属の ssh-keygen は鍵の変換や、ファイルと git コミットへの署名も行います。デフォルトの鍵は Ed25519 で、ML-KEM のハイブリッド鍵交換を最優先し、DSA は削除済みです。また、ECDSA 署名には SSH 独自の mpint エンコーディングを使います。
ライセンス
SSH-OpenSSH
確認したバージョン
10.3p1 ·
ソースコード
github.com/openssh/openssh-portable
ドキュメント
www.openssh.com/manual.html

互換性の概要

ECDSAEdDSAポスト量子暗号

ECDSA の曲線
P-256P-384P-521
EdDSA
Ed25519
公開鍵の形式
spki-pemopensshpkcs1
秘密鍵の形式
pkcs8-pemencrypted-pkcs8sec1-pempkcs1openssh

OpenSSH には、ssh と sshd のほかに、鍵を生成・変換し、-Y sign を指定するとファイルや git コミットに対する SSHSIG 署名も作成する ssh-keygen が含まれています。ここに挙げる事実は、Alpine 3.24.2 のパッケージである OpenSSH 10.3p1(イメージの OpenSSL 3.5.8 にリンク)で確認したものです。-t を指定しないと、ssh-keygen は Ed25519 の鍵を書き出します。ECDSA の鍵は P-256、P-384、P-521 でしか作成できず(-b 224 は拒否されます)、Ed448 はなく、DSA は削除されています。ssh-keygen -t dsa は「unknown key type dsa」と応答します。どの鍵も SSH キーインスペクターで解析できます。

設定ファイルがない場合、クライアントはハイブリッド鍵交換の mlkem768x25519-sha256 を最初に提示し、次に sntrup761x25519-sha512 を提示します。これにより、セッション鍵はポスト量子の保護を受けます。ssh -Q sig にはポスト量子署名アルゴリズムが 1 つもないため、ホスト認証とユーザー認証は従来の方式のままです。SHA-1 を使う RSA(ssh-rsa)は現在も実装されていますが、デフォルトのホスト鍵と公開鍵のアルゴリズム一覧に含まれていないため、デフォルト設定のクライアントがこれを使うことはありません。ssh-rsa より新しいものを何も提示しない相手に対しては、明示的に再有効化する必要があります。たとえばユーザー鍵の場合は PubkeyAcceptedAlgorithms +ssh-rsa を指定します。サーバーが何をネゴシエートするかは SSH サーバー監査で確認してください。

SSH の ECDSA 署名は DER でも生の r‖s でもありません。その署名データは、文字列 ecdsa-sha2-nistp256 のあとに、r と s を SSH の mpint として格納した文字列が続く構造です(RFC 5656)。そのため、X.509、JWS、WebAuthn との間で署名を変換するには、2 つの整数をエンコードし直す必要があります。nonce はランダムで(1 つのファイルに対する 2 つの署名は異なりました)、s は正規化されず、s を n − s に置き換えた署名も検証を通りました。

SSHSIG 署名(ssh-keygen -Y sign)は、デフォルトでメッセージを SHA-512 でハッシュ化します。代わりに使えるのは -O hashalg=sha256 だけで、SHA-1 と SHA-384 は拒否されます。-n で指定した名前空間は署名対象の一部であり、file の署名を email として検証すると「namespace does not match」で失敗します。失敗の種類は stderr で区別でき、壊れたデータには「invalid format」、別のデータに対する有効な署名には「incorrect signature」と表示されますが、stdout はどちらの場合も「Could not verify signature.」と出力します。署名は SSH 署名検証ツールで確認してください。

ssh-keygen -e -m PKCS8 は公開鍵を SPKI の PEM としてエクスポートし、-i -m PKCS8 でそれをインポートし直せます。-m PEM でも ECDSA では SPKI になりますが、RSA では PKCS#1 になり、-m RFC4716 では「SSH2 PUBLIC KEY」形式になります。Ed25519 の公開鍵は -e -m PKCS8 ではエクスポートできませんが(「unsupported key type ED25519」)、-p -m PKCS8 で Ed25519 の秘密鍵を PKCS#8 に書き換えることはできます。秘密鍵はデフォルトで OPENSSH PRIVATE KEY として保存されます。-p -m PEM は ECDSA の鍵を SEC1 に、RSA の鍵を PKCS#1 に書き換え、パスフレーズ付きの -m PKCS8 は暗号化された PKCS#8 を書き出します。

事実とその根拠となるチェック

以下の内容はドキュメントからの転記ではありません。2026年10月20日に、チェック content/libraries/verify/openssh/run.sh がコンテナイメージ alpine:3.24.2 内で OpenSSH (ssh-keygen) 10.3p1 を実行しました。このページの内容はその出力と一致していなければならず、各事実には該当する出力行を示しています。

  • デフォルトの鍵の種類

    ed25519

    -t を指定しない ssh-keygen は ssh-ed25519 の鍵を書き出しました。

    チェックによる記録
    fact default-key-type = ed25519
    evidence default-key-type: ssh-keygen without -t wrote a ssh-ed25519 key
  • ECDSA の曲線

    P-256P-384P-521

    -b 256、384、521 に対応します。-b 224 は「valid lengths are 256, 384 or 521 bits」で拒否されます。

    チェックによる記録
    fact ecdsa-curves = P-256, P-384, P-521
    evidence ecdsa-curves: ssh -Q key: ssh-ed25519 ssh-ed25519-cert-v01@openssh.com sk-ssh-ed25519@openssh.com sk-ssh-ed25519-cert-v01@openssh.com ecdsa-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com ecdsa-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com sk-ecdsa-sha2-nistp256@openssh.com sk-ecdsa-sha2-nistp256-cert-v01@openssh.com ssh-rsa ssh-rsa-cert-v01@openssh.com
  • EdDSA

    Ed25519

    ssh -Q key には ssh-ed25519 とその FIDO 版が表示されます。Ed448 の鍵の種類はありません。

    チェックによる記録
    fact eddsa = Ed25519
  • DSA 鍵

    removed

    ssh-keygen -t dsa は「unknown key type dsa」で失敗し、ssh-dss は ssh -Q key に含まれていません。

    チェックによる記録
    fact dsa-keys = removed
  • デフォルトの鍵交換

    mlkem768x25519-sha256

    ssh -F none -G が出力する kexalgorithms の先頭の項目です。

    チェックによる記録
    fact default-kex = mlkem768x25519-sha256
    evidence default-kex: ssh -F none -G: kexalgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256
  • ポスト量子アルゴリズム

    ML-KEMsntrup761

    mlkem768x25519-sha256 と sntrup761x25519-sha512 のハイブリッド鍵交換に対応します。ssh -Q sig にポスト量子署名アルゴリズムはありません。

    チェックによる記録
    fact pqc = ML-KEM, sntrup761
    evidence pqc: ssh -Q kex: diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group14-sha256 diffie-hellman-group16-sha512 diffie-hellman-group18-sha512 diffie-hellman-group-exchange-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 curve25519-sha256 curve25519-sha256@libssh.org sntrup761x25519-sha512 sntrup761x25519-sha512@openssh.com mlkem768x25519-sha256
    evidence pqc: ssh -Q sig: ssh-ed25519 sk-ssh-ed25519@openssh.com ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521 sk-ecdsa-sha2-nistp256@openssh.com webauthn-sk-ecdsa-sha2-nistp256@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512
  • SHA-1 を使う ssh-rsa 署名

    disabled-by-default

    ssh-rsa は ssh -Q sig にはありますが、デフォルトの pubkeyacceptedalgorithms と hostkeyalgorithms には含まれていません。

    チェックによる記録
    fact ssh-rsa-sha1 = disabled-by-default
    evidence ssh-rsa-sha1: ssh-rsa in ssh -Q sig: yes; in the default pubkeyacceptedalgorithms or hostkeyalgorithms: no
    evidence ssh-rsa-sha1: with -o PubkeyAcceptedAlgorithms=+ssh-rsa it is in the list: yes
  • ECDSA 署名のエンコーディング

    ssh-mpint

    SSHSIG の署名データには、種類を示す文字列と、最小長の SSH mpint で表した r と s が格納されています。

    チェックによる記録
    fact ecdsa-signature-encoding = ssh-mpint
    evidence ecdsa-signature-encoding: ssh-keygen -Y sign: hash=sha512 type=ecdsa-sha2-nistp256 mpints=yes
  • ECDSA の nonce

    random

    1 つのファイルに対する 2 つの署名は異なりました。

    チェックによる記録
    fact ecdsa-nonce = random
    evidence ecdsa-nonce: two signatures of one file are different
  • 署名時の low-S

    either

    s は正規化されません。32 個の署名の中に high-S の値が現れました。

    チェックによる記録
    fact ecdsa-low-s-sign = either
    evidence ecdsa-low-s-sign: signatures with s > n/2 among 32: yes
  • 検証時の high-S

    accepts-high-s

    s を n − s に置き換えた署名も「Good」として検証を通りました。

    チェックによる記録
    fact ecdsa-low-s-verify = accepts-high-s
    evidence ecdsa-low-s-verify: s replaced by n - s: ok
  • 検証失敗時の出力

    distinguishable

    stderr には、生の r‖s と 3 バイトのデータに対して「invalid format」、誤ったメッセージに対して「incorrect signature」と表示されます。終了ステータスはどちらも 255 です。

    チェックによる記録
    fact cli-verify-output = distinguishable
  • SSHSIG のデフォルトのハッシュ

    sha512

    デフォルトの署名の SSHSIG ヘッダーには sha512 が指定されています。

    チェックによる記録
    fact sshsig-default-hash = sha512
    evidence sshsig-default-hash: hash=sha512 type=ecdsa-sha2-nistp256 mpints=yes
  • SSHSIG のハッシュアルゴリズム

    sha256sha512

    -O hashalg= は sha256 と sha512 を受け付け、sha1 と sha384 を拒否しました。

    チェックによる記録
    fact sshsig-hash-algorithms = sha256, sha512
    evidence sshsig-hash-algorithms: ssh-keygen -Y sign -O hashalg= accepted: sha256, sha512
  • SSHSIG の名前空間

    enforced

    -n file で作成した署名は、-n email では「namespace does not match」で失敗しました。

    チェックによる記録
    fact sshsig-namespace = enforced
  • 公開鍵の形式

    spki-pemopensshpkcs1

    SPKI の PEM(-e -m PKCS8 で出力し、-i でインポートし直せます)、OpenSSH の 1 行形式、RSA 向けの PKCS#1(-e -m PEM)です。

    チェックによる記録
    fact public-key-formats = spki-pem, openssh, pkcs1
    evidence public-key-formats: P-256 -e -m PKCS8: -----BEGIN PUBLIC KEY-----, -i back to the same key: yes
    evidence public-key-formats: P-256 -e -m PEM: -----BEGIN PUBLIC KEY-----; -e -m RFC4716: ---- BEGIN SSH2 PUBLIC KEY ----
    evidence public-key-formats: RSA -e -m PEM: -----BEGIN RSA PUBLIC KEY-----, -i back to the same key: yes
  • 秘密鍵の形式

    pkcs8-pemencrypted-pkcs8sec1-pempkcs1openssh

    デフォルトの OpenSSH 形式のほか、PKCS#8、暗号化された PKCS#8、ECDSA の SEC1、RSA の PKCS#1 に対応し、いずれも ssh-keygen -y で読み戻せました。

    チェックによる記録
    fact private-key-formats = pkcs8-pem, encrypted-pkcs8, sec1-pem, pkcs1, openssh
    evidence private-key-formats: P-256 default: -----BEGIN OPENSSH PRIVATE KEY-----; -m PKCS8: -----BEGIN PRIVATE KEY----- (read back: yes); -m PKCS8 with a passphrase: -----BEGIN ENCRYPTED PRIVATE KEY----- (read back: yes); -m PEM: -----BEGIN EC PRIVATE KEY----- (read back: yes)
    evidence private-key-formats: RSA -m PEM: -----BEGIN RSA PRIVATE KEY----- (read back: yes); Ed25519 -m PKCS8: -----BEGIN PRIVATE KEY----- (read back: yes); Ed25519 -m PEM: refused

使い方

Ed25519 の鍵を生成し、`file` 名前空間でファイルに署名して、allowed_signers ファイルに照らして検証します。
# Without -t, ssh-keygen generates an Ed25519 key.
ssh-keygen -q -N "" -C alice@example.com -f id_ed25519
printf 'order #1042 approved\n' > order.txt

# -n names what the signature is for; a different namespace fails verification.
ssh-keygen -q -Y sign -f id_ed25519 -n file order.txt   # writes order.txt.sig

# Verifiers trust keys through allowed_signers: a principal, then the public key.
echo "alice@example.com $(cut -d' ' -f1,2 id_ed25519.pub)" > allowed_signers
ssh-keygen -Y verify -f allowed_signers -I alice@example.com -n file -s order.txt.sig < order.txt

スニペットのテストハーネスは、すべてのサンプルをコンテナイメージ alpine:3.24.2 内でそのまま実行し、出力が一致しなければ実行は失敗します。

セットアップ
apk add --no-cache -q openssh-keygen=10.3_p1-r1 >/dev/null
コマンド
sh sign.sh
一致すべき出力(正規表現)
Good "file" signature for alice@example\.com with ED25519 key SHA256:

ライブラリ