AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1056814
Accepted
Hannes
Hannes
Asked: 2021-03-13 01:40:26 +0800 CST2021-03-13 01:40:26 +0800 CST 2021-03-13 01:40:26 +0800 CST

加密 SSH 私钥的密码安全性:如何读取 bcrypt 的整数或成本因子

  • 772

在这里https://security.stackexchange.com/a/52564您可以阅读到较新的 OpenSSH 版本使用 bcrypt 来保护密钥文件。bcrypt 的安全性取决于成本因素,请参阅https://security.stackexchange.com/questions/139721/estimate-the-time-to-crack-passwords-using-bcrypt/201965#201965

根据https://crypto.stackexchange.com/questions/58536/how-does-openssh-use-bcrypt-to-set-ivs/58543#58543,默认的 bcrypt 轮数为 16。这将是一个很好的安全性. 但是如何获得回合数/成本因素?

到目前为止我所做的:密钥看起来像(为了让它更短,这里只有一个弱的 1024 位密钥)

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBLF8sO2Q
hcLXI43z96e1hiAAAAEAAAAAEAAACXAAAAB3NzaC1yc2EAAAADAQABAAAAgQC0gBWeZpej
9ILT/59bEb0/lSvXx0WfZqP2lXRDbuY+gluuWyT+REQcVTR2BxSx9F/P20mLTnupzY+XE3
xEu+SIJlwKIAH3fed62+QBzDrPsl9kyfoIGIvi/28ZftqVN/kg0GSOaAqu4Px+vNVX1VKn
PNV5VVCZWL4ZPlGQZ48UJwAAAhCwDkueKT9oq8E0qtD92/4DSAD2eTI7bd6jBGUxugEw85
6xWbRYnFQZdwO2ZCNV0aTHViD1FRKlC9cBHDoSORKcM/9dY9Msy6lZj7Tp5s8r7x2pOrJi
TVRbv5/cI732I+l/vYvssJEhZpeSw4JKh9tyPpifVmzBxqtqwkBrTuLCMqkwLmrcxReFUq
aA/RIZy3L616CJsAvx2ezEc49D6SbJ9i9OlKuv73a1baS4RpMvFzWGLE2NBvvtQpEnJFoL
Kyjz+two4doT6SZ7UtiVGyCtO5WQEoeAgjhkbZzOPtM2AvoV+hNLRIX2/52jOB5A1bNQ0v
qW64aj2YNe8vWfj5xtA/8BlyEG7gwhu+0HgbgMDxw7o/0qVkHM/Hv3YgBTRygsH+8h4wsR
kxA292NOKKaD18tv1j3atR80q0XQVcQH20uX8tSqXtKfDtkUc/EPbFCNp3xQJG/F81USKh
YAmjxEeDkZZ/LkEOEJKvFRCL3gFlH4rqF5/pRk6HmB99xceD4irbazm+BWfPAf5Q0zdB5L
/yei3sqA4G48yRXIkaELtYNEeTYHMp3PGz1b3CP3l+ZGZp6XNaM+sMfdICbI3Zae5bnxKg
VXEE2UMdi7DEXbqEzSlfcIf5QzXHMQJm0ZL+iLoaEmakamAxCKk6jJ+QzHzGADZEIRXrj3
5Nhhd0jsToEMsXmmawt2qxy0cIHET1M=
-----END OPENSSH PRIVATE KEY-----

密码是test

然后让我们解码base64。因此必须删除以'-----'开头的第一行和最后一行

cat key | tail -n +2 | head -n -1 | base64 -d > text.txt

现在打开 text.txt 例如在记事本++ 这显示 在此处输入图像描述

但现在我不知道如何从那里读取roundcount。你能帮忙吗?

security password ssh-keys
  • 2 2 个回答
  • 287 Views

2 个回答

  • Voted
  1. Best Answer
    Ian Boyd
    2021-04-11T20:01:16+08:002021-04-11T20:01:16+08:00

    拿你的base64,把它解码成十六进制:

    6f 70 65 6e 73 73 68 2d 6b 65 79 2d 76 31 00 00 00 00 0a 61 65 73 32 35 36 2d 63 74 72 00 00 00 06 
    62 63 72 79 70 74 00 00 00 18 00 00 00 10 4b 17 cb 0e d9 08 5c 2d 72 38 df 3f 7a 7b 58 62 00 00 00 
    10 00 00 00 01 00 00 00 97 00 00 00 07 73 73 68 2d 72 73 61 00 00 00 03 01 00 01 00 00 00 81 00 b4 
    80 15 9e 66 97 a3 f4 82 d3 ff 9f 5b 11 bd 3f 95 2b d7 c7 45 9f 66 a3 f6 95 74 43 6e e6 3e 82 5b ae 
    5b 24 fe 44 44 1c 55 34 76 07 14 b1 f4 5f cf db 49 8b 4e 7b a9 cd 8f 97 13 7c 44 bb e4 88 26 5c 0a 
    20 01 f7 7d e7 7a db e4 01 cc 3a cf b2 5f 64 c9 fa 08 18 8b e2 ff 6f 19 7e da 95 37 f9 20 d0 64 8e 
    68 0a ae e0 fc 7e bc d5 57 d5 52 a7 3c d5 79 55 50 99 58 be 19 3e 51 90 67 8f 14 27 00 00 02 10 b0 
    0e 4b 9e 29 3f 68 ab c1 34 aa d0 fd db fe 03 48 00 f6 79 32 3b 6d de a3 04 65 31 ba 01 30 f3 9e b1 
    59 b4 58 9c 54 19 77 03 b6 64 23 55 d1 a4 c7 56 20 f5 15 12 a5 0b d7 01 1c 3a 12 39 12 9c 33 ff 5d 
    63 d3 2c cb a9 59 8f b4 e9 e6 cf 2b ef 1d a9 3a b2 62 4d 54 5b bf 9f dc 23 bd f6 23 e9 7f bd 8b ec 
    b0 91 21 66 97 92 c3 82 4a 87 db 72 3e 98 9f 56 6c c1 c6 ab 6a c2 40 6b 4e e2 c2 32 a9 30 2e 6a dc 
    c5 17 85 52 a6 80 fd 12 19 cb 72 fa d7 a0 89 b0 0b f1 d9 ec c4 73 8f 43 e9 26 c9 f6 2f 4e 94 ab af 
    ef 76 b5 6d a4 b8 46 93 2f 17 35 86 2c 4d 8d 06 fb ed 42 91 27 24 5a 0b 2b 28 f3 fa dc 28 e1 da 13 
    e9 26 7b 52 d8 95 1b 20 ad 3b 95 90 12 87 80 82 38 64 6d 9c ce 3e d3 36 02 fa 15 fa 13 4b 44 85 f6 
    ff 9d a3 38 1e 40 d5 b3 50 d2 fa 96 eb 86 a3 d9 83 5e f2 f5 9f 8f 9c 6d 03 ff 01 97 21 06 ee 0c 21 
    bb ed 07 81 b8 0c 0f 1c 3b a3 fd 2a 56 41 cc fc 7b f7 62 00 53 47 28 2c 1f ef 21 e3 0b 11 93 10 36 
    f7 63 4e 28 a6 83 d7 cb 6f d6 3d da b5 1f 34 ab 45 d0 55 c4 07 db 4b 97 f2 d4 aa 5e d2 9f 0e d9 14 
    73 f1 0f 6c 50 8d a7 7c 50 24 6f c5 f3 55 12 2a 16 00 9a 3c 44 78 39 19 67 f2 e4 10 e1 09 2a f1 51 
    08 bd e0 16 51 f8 ae a1 79 fe 94 64 e8 79 81 f7 dc 5c 78 3e 22 ad b6 b3 9b e0 56 7c f0 1f e5 0d 33 
    74 1e 4b ff 27 a2 de ca 80 e0 6e 3c c9 15 c8 91 a1 0b b5 83 44 79 36 07 32 9d cf 1b 3d 5b dc 23 f7 
    97 e6 46 66 9e 97 35 a3 3e b0 c7 dd 20 26 c8 dd 96 9e e5 b9 f1 2a 05 57 10 4d 94 31 d8 bb 0c 45 db 
    a8 4c d2 95 f7 08 7f 94 33 5c 73 10 26 6d 19 2f e8 8b a1 a1 26 6a 46 a6 03 10 8a 93 a8 c9 f9 0c c7 
    cc 60 03 64 42 11 5e b8 f7 e4 d8 61 77 48 ec 4e 81 0c b1 79 a6 6b 0b 76 ab 1c b4 70 81 c4 4f 53 
    

    规范定义了该数据的格式。然后我们可以将数据分开:

        byte[]  AUTH_MAGIC = "openssh-key-v1\n"
        string  ciphername
        string  kdfname
        string  kdfoptions
        int     number of keys N
        string  publickey1
        string  publickey2
        ...
        string  publickeyN
        string  encrypted, padded list of private keys
    
    6f 70 65 6e 73 73 68 2d 6b 65 79 2d 76 31 00        AUTH_MAGIC "openssh-key-v1\n"
    00 00 00 0a                     CipherName string length. 0x0000000a = 10 characters
    61 65 73 32 35 36 2d 63 74 72               CipherName "aes256-ctr"
    00 00 00 06                     KdfName length prefix  0x00000006 = 6 characters
    62 63 72 79 70 74                   KdfName "bcrypt"
    00 00 00 18                     KdfOptions string length prefix. 0x00000018 = 24 characters 
    00 00 00 10 4b 17 cb 0e d9 08 5c 2d 
    72 38 df 3f 7a 7b 58 62 00 00 00 10 
    
    00 00 00 01                     Number of keys. 0x00000001 = 1;
    
    00 00 00 97                     publicKey1 string length  0x00000097
    00 00 00 07 73 73 68 2d 72 73 61 00 00 00 03 01     publicKey1
    00 01 00 00 00 81 00 b4 80 15 9e 66 97 a3 f4 82 
    d3 ff 9f 5b 11 bd 3f 95 2b d7 c7 45 9f 66 a3 f6 
    95 74 43 6e e6 3e 82 5b ae 5b 24 fe 44 44 1c 55 
    34 76 07 14 b1 f4 5f cf db 49 8b 4e 7b a9 cd 8f 
    97 13 7c 44 bb e4 88 26 5c 0a 20 01 f7 7d e7 7a 
    db e4 01 cc 3a cf b2 5f 64 c9 fa 08 18 8b e2 ff 
    6f 19 7e da 95 37 f9 20 d0 64 8e 68 0a ae e0 fc 
    7e bc d5 57 d5 52 a7 3c d5 79 55 50 99 58 be 19 
    3e 51 90 67 8f 14 27 
    00 00 02 10                     publicKey2 string length 0x00000210 = frazillion characters
    b0 0e 4b 9e 29 3f 68 ab c1 34 aa d0 fd db fe 03 
    48 00 f6 79 32 3b 6d de a3 04 65 31 ba 01 30 f3 
    9e b1 59 b4 58 9c 54 19 77 03 b6 64 23 55 d1 a4 
    c7 56 20 f5 15 12 a5 0b d7 01 1c 3a 12 39 12 9c 
    33 ff 5d 63 d3 2c cb a9 59 8f b4 e9 e6 cf 2b ef 
    1d a9 3a b2 62 4d 54 5b bf 9f dc 23 bd f6 23 e9 
    7f bd 8b ec b0 91 21 66 97 92 c3 82 4a 87 db 72 
    3e 98 9f 56 6c c1 c6 ab 6a c2 40 6b 4e e2 c2 32 
    a9 30 2e 6a dc c5 17 85 52 a6 80 fd 12 19 cb 72 
    fa d7 a0 89 b0 0b f1 d9 ec c4 73 8f 43 e9 26 c9 
    f6 2f 4e 94 ab af ef 76 b5 6d a4 b8 46 93 2f 17 
    35 86 2c 4d 8d 06 fb ed 42 91 27 24 5a 0b 2b 28 
    f3 fa dc 28 e1 da 13 e9 26 7b 52 d8 95 1b 20 ad 
    3b 95 90 12 87 80 82 38 64 6d 9c ce 3e d3 36 02 
    fa 15 fa 13 4b 44 85 f6 ff 9d a3 38 1e 40 d5 b3 
    50 d2 fa 96 eb 86 a3 d9 83 5e f2 f5 9f 8f 9c 6d 
    03 ff 01 97 21 06 ee 0c 21 bb ed 07 81 b8 0c 0f 
    1c 3b a3 fd 2a 56 41 cc fc 7b f7 62 00 53 47 28 
    2c 1f ef 21 e3 0b 11 93 10 36 f7 63 4e 28 a6 83 
    d7 cb 6f d6 3d da b5 1f 34 ab 45 d0 55 c4 07 db 
    4b 97 f2 d4 aa 5e d2 9f 0e d9 14 73 f1 0f 6c 50 
    8d a7 7c 50 24 6f c5 f3 55 12 2a 16 00 9a 3c 44 
    78 39 19 67 f2 e4 10 e1 09 2a f1 51 08 bd e0 16 
    51 f8 ae a1 79 fe 94 64 e8 79 81 f7 dc 5c 78 3e 
    22 ad b6 b3 9b e0 56 7c f0 1f e5 0d 33 74 1e 4b 
    ff 27 a2 de ca 80 e0 6e 3c c9 15 c8 91 a1 0b b5 
    83 44 79 36 07 32 9d cf 1b 3d 5b dc 23 f7 97 e6 
    46 66 9e 97 35 a3 3e b0 c7 dd 20 26 c8 dd 96 9e 
    e5 b9 f1 2a 05 57 10 4d 94 31 d8 bb 0c 45 db a8 
    4c d2 95 f7 08 7f 94 33 5c 73 10 26 6d 19 2f e8 
    8b a1 a1 26 6a 46 a6 03 10 8a 93 a8 c9 f9 0c c7 
    cc 60 03 64 42 11 5e b8 f7 e4 d8 61 77 48 ec 4e 
    81 0c b1 79 a6 6b 0b 76 ab 1c b4 70 81 c4 4f 53 
    

    KDF 选项字符串

    您想要的部分是字符串kdfOptions:

    00 00 00 10 4b 17 cb 0e d9 08 5c 2d 72 38 df 3f 7a 7b 58 62 00 00 00 10

    规范解释:

        string salt
        uint32 rounds
    

    换句话说:

    00 00 00 10                  Salt string length 0x00000010 = 16 characters
    4b 17 cb 0e d9 08 5c 2d 72 38 df 3f 7a 7b 58 62   Salt
    00 00 00 10                  Number of rounds. 0x00000010 = 16 
    

    我怀疑他们的意思是“回合”。我认为他们的意思是CostFactor。

    • 成本因数 16 ⇒ 回合 = 2 16 = 65,535 回合
    • 成本因子 4 ⇒ 轮数 = 2 4 = 16 轮

    但它就在那里。

    Bcrypt 不是 KDF

    BCrypt 不是密钥派生函数;这是一个密码存储功能。您不能使用 bcrypt 生成“密钥”。例如,如果您想“派生”一个 AES-256 位密钥:bcrypt 无法做到。

    那是因为 bcrypt 不是密钥派生函数。
    BCrypt 是一个密码散列函数。

    以这种方式滥用 bcrypt 是一种可憎的行为,也是一种反人类罪。

    有关 bcrypt 作为密码散列函数而不是密钥派生函数的更多信息,请参见https://crypto.stackexchange.com/a/70783

    • 2
  2. Hannes
    2022-04-03T13:11:26+08:002022-04-03T13:11:26+08:00

    一些额外的信息。回顾一下新 ssh 密钥的密码保护是非常安全的。

    创建密钥或更改密码时,您可以使用-a <number of rounds>.

    time ssh-keygen -f 2.key -p -a 500 -P b -N b #needs 10 seconds
    time ssh-keygen -f 2.key -p -a 1000 -P b -N b #needs 15 seconds
    time ssh-keygen -f 2.key -p -a 1000 -P b -N b #needs 20 seconds
    time ssh-keygen -f 2.key -p -a 1000 -P b -N b #needs 20 seconds, 10 to encrypt, 10 to decrypt
    

    这是在旧的 i3-3220 上完成的,大约需要 Ryzen 7 5700U 一半的时间。所以回合确实是回合而不是成本因素。

    要确定您的密钥是否是新格式,请使用cat key | tail -n +2 | head -n -1 | base64 -d | head -n 2 如果您看到aes256-ctrbcrypt,那么您的密钥是新格式。

    为了估计它对暴力密码猜测的安全性,我使用了 John the ripper。Hashcat 目前(2022 年 3 月)不支持这种格式,请参阅https://hashcat.net/forum/thread-10662.html 为开膛手约翰预构建的二进制文件也可能不包含用于破解这种新型 ssh 密钥的必要模块格式。

    编译 John 后,开膛手转到run目录并通过 SSH 密钥文件创建哈希python3 ssh2john.py <keyfile> > hash.txt

    现在通过./john hash.txt. 程序将使用随附的密码列表。在 AMD Ryzen 7 5700U 上,它可以尝试大约 132 PW/s (c/s),这是一个非常低的数字。这只是 CPU。当通过-a 32数字将轮次更改为 32 时,预期会减半(65 PW/s)。

    为了估计使用 GPU 可能会发生什么,我还使用了 MD5 加密哈希,并且使用这个 John the Ripper 每秒能够尝试大约 712,000 个密码,因此速度快了大约 5400 倍。

    当你将它与 GTX1080 进行比较时,它每秒能够使用 MD5Crypt https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a270c40处理大约 1000 万个密码, 所以如果这是线性的,那么 GTX 1080 比 Ryzen 7 5700U 快大约 14 倍,所以只有大约 1850 PW/s 应该是可能的。

    所以目前的 sshkey 加密对于离线攻击是相当安全的。

    最后,一个小 python 脚本接受filename="test.key"你的 ssh 密钥,如果它是 bcrypt 格式,它会显示盐和成本因素。

    #!/usr/bin/python3
    
    import binascii
    import base64
    import re
    filename="2.key"
    with open(filename, 'r') as f:
        content = f.read()
    content = content.split("\n")
    content=content[1:-1]
    content="".join(content)
    #print(content)
    decoded=base64.b64decode(content)
    #print(decoded)
    hex=binascii.hexlify(decoded)
    #print(type(hex))
    #print(hex)
    bycryptPattern="626372797074"
    begin=str(hex).find(bycryptPattern)
    if begin == -1:
        print("No encryption based on bcrypt. Exiting...")
        exit(1)
    begin+=len(bycryptPattern)
    content=str(hex)[begin:]
    kdfOptionsLength=content[:8]
    content=content[8:]
    kdfOptionsLength=int(kdfOptionsLength,16)
    kdfPart=content[:kdfOptionsLength*2]
    saltLen=int(kdfPart[:8],16)
    kdfPart=kdfPart[8:]
    salt=re.findall("..",kdfPart[:saltLen*2])
    salt=" ".join(salt)
    print("Salt:", salt)
    kdfPart=kdfPart[saltLen*2:]
    rounds=int(kdfPart,16)
    print(f"encryption rounds: {rounds} ")
    
    • 0

相关问题

  • OpenSSH 漏洞 [重复]

  • 选择什么安全套件?

  • 安全地授予对 SQL 2005 复制监视器的访问权限以创建快照

  • SSH 服务器零日漏洞利用 - 保护自己的建议

  • 如何将安全组添加到正在运行的 EC2 实例?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve