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

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

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

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

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

答案1

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

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

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

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

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

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

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

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

  • 盐 (string
  • 轮数 ( uint32)

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

$ <id_ed25519 grep -v '^-' | base64 -d | xxd -g1
00000000: 6f 70 65 6e 73 73 68 2d 6b 65 79 2d 76 31 00 00  openssh-key-v1..
00000010: 00 00 0a 61 65 73 32 35 36 2d 63 74 72 00 00 00  ...aes256-ctr...
00000020: 06 62 63 72 79 70 74 00 00 00 18 00 00 00 10 fe  .bcrypt.........
00000030: 57 c1 fe c6 47 cf 63 34 ef 83 35 61 aa f6 31 00  W...G.c4..5a..1.
00000040: 00 00 15 00 00 00 01 00 00 00 33 00 00 00 0b 73  ..........3....s
00000050: 73 68 2d 65 64 32 35 35 31 39 00 00 00 20 7b c8  sh-ed25519... {.

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

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

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

$ pip install -U openssh-key-parser
$ python3 -m openssh_key id_ed25519 | jq '.header.kdf'
Key passphrase: 
"bcrypt"
$ python3 -m openssh_key id_ed25519 | jq '.kdf_options.data.rounds'
Key passphrase: 
21

相关内容