长话短说

长话短说

问题很简单:

什么是(私钥)类型和(他们的规格- 当前接受的格式、语法)开放SSH

模糊的答案“由”生成的密钥ssh-keygen不被接受 - 我知道。它们被称为 PEM,具有以下标头(RSA、DSA、ECDSA 变体):

-----BEGIN RSA PRIVATE KEY-----

另一种格式描述于协议密钥并由 扩展openssh。它也用作Ed25519密钥的默认值,如手册中所述和标有标题的(无论密码短语):

-----BEGIN OPENSSH PRIVATE KEY-----

还有一些遗留RSA1密钥现在应该随 SSHv1 协议一起消失,但可以通过标头识别:

SSH PRIVATE KEY FILE FORMAT 1.1

还有其他人吗?我正在寻找其他键的更详细描述。我没有发现它(到目前为止)在任何手册页或任何 SSH 的 RFC 中明确指定。

奖金问题(不需要回答,但我很欣赏您的见解):

openssh( ) 解码每个虚拟文件并要求输入密码,即使它没有正确的标头,其背后的原因是什么?


脚注:问题最初发布于openssh-unix-dev 列表,但到目前为止还没有任何答案,所以我正在尝试这个很棒的社区,如果有人能够回答的话。

答案1

长话短说

来自@forcefsck 的最有帮助的评论。不幸的是,他没有填写答案,所以我无法授予赏金。简而言之,答案是质子交换膜+RSA1+ 问题中描述的新 openSSH 格式,主要问题在于 PEM。

长篇和奖金

OpenSSH 使用 openSSL ( PEM_read_bio_PrivateKey()) 的解析器,它对所有失败 ( NULL) 有唯一的返回值,如果失败,openSSH 认为这是因为密码错误。

没有 OpenSSL

我只是尝试在没有 OpenSSL 支持(配置选项)的情况下构建 OpenSSH --without-openssl,并且行为是“正确的”:

# ./ssh-add <(echo "")
Error loading key "/dev/fd/63": invalid format

使用 OpenSSL 修复

另一件事是如何解决它。 poke 来自ERR_get_error()函数及其朋友,这应该允许我们区分不同的错误。

密码错误错误

# ./ssh-add /tmp/rsa
140480353842840:error:0906A068:lib(9):func(106):reason(104):pem_lib.c:457:
Enter passphrase for /tmp/rsa: 
140480353842840:error:06065064:lib(6):func(101):reason(100):evp_enc.c:592:
140480353842840:error:0906A065:lib(9):func(106):reason(101):pem_lib.c:482:

理由:PEM_R_BAD_PASSWORD_READPEM_R_BAD_BASE64_DECODEPEM_R_BAD_DECRYPT

解析错误代码

# ./ssh-add <(echo "")
139656018548376:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:701:Expecting: ANY PRIVATE KEY

或这个:

140654301202072:error:0906D066:lib(9):func(109):reason(102):pem_lib.c:809:

原因:PEM_R_NO_START_LINE,,PEM_R_BAD_END_LINE但是可能还有更多的可能性。

解决方案?

添加更多 OpenSSL 错误检查应该可以让我们选择将哪个错误标记为“格式”错误,哪个错误标记为“错误密码”。该位置位于3800附近的功能线上sshkey_parse_private_pem_fileblob()sshkey.c

unsigned long e = ERR_get_error();
if (ERR_GET_REASON(e) == PEM_R_NO_START_LINE ||
    ERR_GET_REASON(e) == PEM_R_BAD_END_LINE) {
        r = SSH_ERR_INVALID_FORMAT;
} else {
        r = SSH_ERR_KEY_WRONG_PASSPHRASE;
}

相关内容