首页 > 解决方案 > 检查 SSH 私钥是否已加密

问题描述

在 macOS 上生成的密钥对ssh-keygen可以有不同的格式。

OpenSSH/BSD在这里使用这种非标准化格式。

现在我只需要能够检查一个私钥是否设置了密码,这样我就可以提示用户输入它,而不必处理不同密钥格式的复杂性。

在 macOS 上是否有一种通过 Swift 或 C API 快速检查密钥是否设置密码的方法?

标签: cswiftmacosssh

解决方案


未加密和加密的私钥之间的区别在于密钥 blob 是加密的。您需要先解密私钥 blob 数据,然后才能使用私钥 blob。所以一旦加密的私钥数据被解码,就可以和未加密的私钥数据一样对待。

未加密的私钥 blob PEM 文件如下所示:

—–BEGIN PRIVATE KEY—–
{base64 private key blob)
—–END PRIVATE KEY—–

加密的 RSA 私钥 PEM 文件如下所示:

—–BEGIN RSA PRIVATE KEY—–
Proc-Type: 4,ENCRYPTED
DEK-Info: {encryption algorithm},{salt}
{base64 encrypted private key blob)
—–END RSA PRIVATE KEY—–

例如

—–BEGIN RSA PRIVATE KEY—–
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,AB8E2B5B2D989271273F6730B6F9C687
{base64 encrypted private key blob)
—–END RSA PRIVATE KEY—–

因此,要解码您需要的私钥数据:

  1. 解析DEK-Info加密算法和 salt(确认第一行的好主意是:“ Proc-Type : 4,ENCRYPTED”)。
  2. 解码 base64 加密的私钥 blob。
  3. 根据盐和密码生成加密算法“密钥”和“IV”
  4. 解码加密的私钥 blob。

完成后,解密的私钥 blob 可以像未编码的私钥 blob 一样处理。

支持的加密算法的数量相当大,因此您可能希望支持一组算法。例如“DES-EDE3-CBC”、“AES-xxx-CBC”等

要生成 IV,您需要将盐字符串转换为二进制。salt 字符串是一个十六进制编码的字符串,因此使用十六进制字符串字符到字节转换器将每两个字符串字符转换为一个字节。

为了生成加密算法密钥,您需要密钥大小(例如 DES-EDE3-CBC 是 192 位,AES-256-CBC 是 256 位)。通过将 MD5 哈希结果附加到密钥的循环来构建密钥“位”,直到生成所需的所有密钥位。

MD5 HASH 循环生成将包括:

  1. First MD5 Hash:IV 和 Passphrase 的前 8 个字节的 MD5 哈希
  2. 所有其他 MD5 哈希是最后一个 MD5 哈希结果和 IV 和密码短语的前 8 个字节的 MD5 哈希

有关密钥位生成的示例,请参阅EVP_BytesToKey方法的 openssl 源代码。

现在可以使用上面的 IV 和 KEY 构建使用选定的加密算法对加密的私钥 blob 进行解码。


推荐阅读