如何查看 Ed25519 SSH 密钥的 KDF 轮数?

Son*_*ony 4 ssh

Ed25519 可以使用以下命令通过特定数量的 KDF 轮次生成 SSH 密钥:

ssh-keygen -t ed25519 -a 21(默认为 16)

给定文件id_ed25519id_ed25519.pub,如何找到这个轮数?

Gil*_*il' 6

请注意,这是私钥文件的属性,而不是私钥的属性。它用于从密码短语中派生密钥加密密钥(作为基于密码的密钥派生函数的参数)。您可以在更改密码时更改轮数ssh-keygen -p

\n

似乎没有办法找到这个属性ssh-keygenssh-keygen -l -v仅显示密钥的属性和一些关联的元数据,不包括密钥的加密方式。

\n

私钥文件格式部分记录在PROTOCOL.key. 我的回答是基于此、基于源码阅读和实验观察。

\n

OpenSSH 私钥的本机格式由包裹在两行-----BEGIN OPENSSH PRIVATE KEY-----和之间的 Base64 编码数据组成-----END OPENSSH PRIVATE KEY-----PROTOCOL.key描述 Base64 编码的二进制数据的内容。二进制数据是以下类型的字段序列:

\n
    \n
  • byte[]:预先知道长度的字节串。
  • \n
  • string:一串字节,其长度在字符串之前编码为 4 字节大端数字。
  • \n
  • uint32int:一个 4 字节数字编码的大尾数。
  • \n
\n

二进制数据包含以下字段:

\n
    \n
  • 文字字符串openssh-key-v1\xe2\x90\x80,其中\xe2\x90\x80有空字节 ( byte[])
  • \n
  • 密码名称 (例如aes256-ctr) ( string)
  • \n
  • PBKDF 名称(自 OpenSSH 8.1 起:bcryptnone)( string)
  • \n
  • PBKDF 选项 ( string)
  • \n
  • (我们不关心其余的)
  • \n
\n

PBKDF 选项本身被构造为一系列字段。对于bcrypt,它们是:

\n
    \n
  • 盐 (string
  • \n
  • 轮数 ( uint32)
  • \n
\n

以下是如何直观地检查私钥文件以查找 KDF 信息。

\n
$ <id_ed25519 grep -v \'^-\' | base64 -d | xxd -g1\n00000000: 6f 70 65 6e 73 73 68 2d 6b 65 79 2d 76 31 00 00  openssh-key-v1..\n00000010: 00 00 0a 61 65 73 32 35 36 2d 63 74 72 00 00 00  ...aes256-ctr...\n00000020: 06 62 63 72 79 70 74 00 00 00 18 00 00 00 10 fe  .bcrypt.........\n00000030: 57 c1 fe c6 47 cf 63 34 ef 83 35 61 aa f6 31 00  W...G.c4..5a..1.\n00000040: 00 00 15 00 00 00 01 00 00 00 33 00 00 00 0b 73  ..........3....s\n00000050: 73 68 2d 65 64 32 35 35 31 39 00 00 00 20 7b c8  sh-ed25519... {.\n\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

从一开始,遵循三个人类可读的字符串 ( openssh-key-v1aes256-ctrbcrypt。之后,有一个包含 PBKDF 选项的复合字符串,由 24 个字节组成,前面是00 00 00 18。这 24 个字节包括:

\n
    \n
  • 盐长度 ( 00 00 00 10)。
  • \n
  • 盐(由盐长度指示的 16 个字节)。
  • \n
  • 轮数 ( 00 00 00 15) \xe2\x80\x94 即 0x15 = 21。
  • \n
\n

如果您想以编程方式提取此内容,而不是编写自己的脚本,可以使用一个 Python 库openssh-key-parser

\n
$ pip install -U openssh-key-parser\n\xe2\x80\xa6\n$ python3 -m openssh_key id_ed25519 | jq \'.header.kdf\'\nKey passphrase: \n"bcrypt"\n$ python3 -m openssh_key id_ed25519 | jq \'.kdf_options.rounds\'\nKey passphrase: \n21\n
Run Code Online (Sandbox Code Playgroud)\n