c - 检查 SSH 私钥是否已加密
问题描述
在 macOS 上生成的密钥对ssh-keygen
可以有不同的格式。
SecKey
macOS 的API可读的标准 PEM ASN.1 对象- 带有文本标题的 PEM
- OpenSSH 密钥
- OpenSSH 加密密钥
OpenSSH/BSD在这里使用这种非标准化格式。
现在我只需要能够检查一个私钥是否设置了密码,这样我就可以提示用户输入它,而不必处理不同密钥格式的复杂性。
在 macOS 上是否有一种通过 Swift 或 C API 快速检查密钥是否设置密码的方法?
解决方案
未加密和加密的私钥之间的区别在于密钥 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—–
因此,要解码您需要的私钥数据:
- 解析DEK-Info加密算法和 salt(确认第一行的好主意是:“ Proc-Type : 4,ENCRYPTED”)。
- 解码 base64 加密的私钥 blob。
- 根据盐和密码生成加密算法“密钥”和“IV”
- 解码加密的私钥 blob。
完成后,解密的私钥 blob 可以像未编码的私钥 blob 一样处理。
支持的加密算法的数量相当大,因此您可能希望支持一组算法。例如“DES-EDE3-CBC”、“AES-xxx-CBC”等
要生成 IV,您需要将盐字符串转换为二进制。salt 字符串是一个十六进制编码的字符串,因此使用十六进制字符串字符到字节转换器将每两个字符串字符转换为一个字节。
为了生成加密算法密钥,您需要密钥大小(例如 DES-EDE3-CBC 是 192 位,AES-256-CBC 是 256 位)。通过将 MD5 哈希结果附加到密钥的循环来构建密钥“位”,直到生成所需的所有密钥位。
MD5 HASH 循环生成将包括:
- First MD5 Hash:IV 和 Passphrase 的前 8 个字节的 MD5 哈希
- 所有其他 MD5 哈希是最后一个 MD5 哈希结果和 IV 和密码短语的前 8 个字节的 MD5 哈希
有关密钥位生成的示例,请参阅EVP_BytesToKey方法的 openssl 源代码。
现在可以使用上面的 IV 和 KEY 构建使用选定的加密算法对加密的私钥 blob 进行解码。
推荐阅读
- .net - 如何在 Windows Server 2012 R2 上安装 .net framework 4.6.1 运行时
- html - 在 CSS 中突出显示右边距较短的文本
- python - Python:函数中的凯撒密码ASCII码
- c++ - 列出在 Linux 上使用 C/C++ 执行的程序中的共享库
- java - JavaFX css 不适用于 TabPane
- shell - 键值对中键的唯一计数,使用 shell 脚本的第一行除外
- android - ScrollView 未检测到内容大小变化
- python - 如何在 PySpark 中找到数组数组的平均值
- python - 如何修复python中的超出范围错误?
- c++ - 递归似乎只在一定程度上起作用——如何调试这些问题?