关于ssh-keygen 生成的key以“BEGIN OPENSSH PRIVATE KEY”开头

本文介绍因SSH密钥格式变化导致的mysql、MongoDB等应用认证失败问题,包括如何使用ssh-keygen命令生成旧格式密钥及将新格式密钥转换为旧格式的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在使用命令 ssh-keygen -t rsa  生成ssh,默认是以新的格式生成,id_rsa的第一行变成了“BEGIN OPENSSH PRIVATE KEY” 而不在是“BEGIN RSA PRIVATE KEY”,此时用来msyql、MongoDB,配置ssh登陆的话,可能会报 “Resource temporarily unavailable. Authentication by key (/Users/youname/.ssh/id_rsa) failed (Error -16). (Error #35)” 提示资源不可用,这就是id_rsa 格式不对造成的

解决方法(一):

使用 ssh-keygen -m PEM -t rsa -b 4096 来生成

-m 参数指定密钥的格式,PEM(也就是RSA格式)是之前使用的旧格式

-b:指定密钥长度;

-e:读取openssh的私钥或者公钥文件;

-C:添加注释;

-f:指定用来保存密钥的文件名;

-i:读取未加密的ssh-v2兼容的私钥/公钥文件,然后在标准输出设备上显示openssh兼容的私钥/公钥;

-l:显示公钥文件的指纹数据;

-N:提供一个新密语;

-P:提供(旧)密语;

-q:静默模式;

-t:指定要创建的密钥类型

 

解决方法(二):

将密钥转换为PuTTy ppk格式并返回来解决

tempkey的内容:

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAA...
-----END OPENSSH PRIVATE KEY-----
```
转换为ppk格式:
`puttygen tempkey -o tempkey.ppk`

转换回openssh格式:
`puttygen tempkey.ppk -O private-openssh -o tempkey.oldformat`

tempkey.oldformat的内容:

```
-----BEGIN RSA PRIVATE KEY-----
MIIJJwIBAAKCAgEAzmmS5aA0....
-----END RSA PRIVATE KEY-----
```

参考地址:https://github.com/duplicati/duplicati/issues/3360

<think>嗯,用户现在想判断一个给定的字符串是否是PEM格式。根据他们提供的示例内容:`-----BEGIN PRIVATE KEY-----MDM5ODk4OTMzNjExM2FiYjViMGIyNDUzZjRhNGJiYTE6Cg==-----END PRIVATE KEY-----`,我需要分析是否符合PEM的结构要求。 首先,回顾一下PEM的基本结构。PEM格式通常包含三个部分:头部标记、Base64编码的内容和尾部标记。头部和尾部必须包含正确的BEGIN和END标签,例如`-----BEGIN PRIVATE KEY-----`和`-----END PRIVATE KEY-----`。用户提供的字符串确实有这些标记,但看起来中间的内容是MD5哈希后的Base64编码,这可能不符合PEM的要求,因为PEM的内容应该是DER结构的Base64编码。 接下来,检查内容部分。Base64编码的数据通常每行64个字符,但用户的示例中的内容只有一行,而且长度较短。虽然PEM允许单行,但实际应用中,密钥或证书的Base64内容会更长,且可能包含换行。此外,MD5哈希后的字符串可能不是有效的DER结构,这会导致解析失败。 然后,用户提供的引用中提到,不同工具生成的PEM可能有不同的头部标签,比如`BEGIN RSA PRIVATE KEY`和`BEGIN OPENSSH PRIVATE KEY`。这说明判断PEM格式时,需要验证头部和尾部的标签是否匹配,并且是否属于已知的类型。例如,用户的示例中使用的是`PRIVATE KEY`,这可能表示PKCS#8格式,而旧版可能是RSA PRIVATE KEY。需要确保标签的准确性。 另外,用户之前的问题涉及将不同格式的密钥转换为PEM或PPK,所以在判断时可能需要考虑这些转换过程中的格式变化。例如,使用OpenSSL生成的PEM文件可能有不同的结构和编码方式。 最后,用户可能需要一个编程上的解决方案,比如正则表达式,来验证字符串是否符合PEM的结构。需要注意标签的正确性、Base64内容的有效性,以及可能的换行符处理。同时,要提醒用户即使结构正确,内容是否有效还需进一步解析。</think>### 分步判断PEM格式的步骤 #### 一、格式结构验证 1. **头部/尾部标记匹配性** ```python # 正则表达式匹配标准PEM标记 import re pem_content = """-----BEGIN PRIVATE KEY----- MDM5ODk4OTMzNjExM2FiYjViMGIyNDUzZjRhNGJiYTE6Cg== -----END PRIVATE KEY-----""" pattern = r"-----BEGIN ([A-Z ]+)-----\n([A-Za-z0-9+/=\n]+)\n-----END \1-----" match = re.fullmatch(pattern, pem_content) if match: print("基础结构验证通过") else: print("标记不匹配或格式错误") ``` - **验证结果**:此处示例中`BEGIN PRIVATE KEY`与`END PRIVATE KEY`标签匹配,但实际内容存在异常(见下文分析)[^1][^4]。 #### 二、Base64内容验证 1. **编码规则检查** ```python import base64 encoded_data = "MDM5ODk4OTMzNjExM2FiYjViMGIyNDUzZjRhNGJiYTE6Cg==" try: decoded = base64.b64decode(encoded_data, validate=True) print("Base64编码有效") except Exception as e: print(f"Base64解码失败:{str(e)}") ``` - **验证结果**:该字符串能通过Base64解码,但解码后的二进制数据**并非有效的DER结构**(例如私钥DER应包含ASN.1编码)[^3][^4]。 #### 三、密钥类型兼容性验证 1. **头部标记语义分析** | 头部标记类型 | 实际含义 | 示例场景 | |-----------------------|----------------------------------|-------------------------| | `BEGIN PRIVATE KEY` | PKCS#8格式私钥 | OpenSSL默认生成的私钥 | | `BEGIN RSA PRIVATE KEY` | 传统PEM格式RSA私钥 | 旧版MySQL认证文件 | | `BEGIN OPENSSH PRIVATE KEY` | OpenSSH专有格式 | 新版ssh-keygen生成文件 | **结论**:示例中的`BEGIN PRIVATE KEY`标记表示PKCS#8格式,但内容`MDM5...`明显不符合DER编码规范(应为ASN.1结构)[^4]。 #### 四、综合判断 根据上述分析,虽然该字符串**满足PEM格式的文本结构要求**,但存在两个关键问题: 1. **内容非法性**:Base64解码后的数据不是合法的密钥DER编码 2. **语义不匹配**:`PRIVATE KEY`标签通常对应非对称加密私钥,但示例内容更像是哈希值 #### 五、改进建议 若需生成合法的PEM私钥,应使用标准工具: ```bash # 生成合规的PKCS#8私钥 openssl genpkey -algorithm RSA -out private.pem ``` ### 代码实现PEM验证函数 ```python import re import base64 def is_valid_pem(content: str) -> bool: # 结构验证 pem_pattern = re.compile( r"-----BEGIN ([A-Z ]+)-----\n" r"([A-Za-z0-9+/=\n]+)\n" r"-----END \1-----", re.MULTILINE ) match = pem_pattern.fullmatch(content) if not match: return False # Base64内容验证 try: base64_content = match.group(2).replace("\n", "") decoded = base64.b64decode(base64_content, validate=True) return len(decoded) > 0 # 简单校验二进制数据有效性 except: return False # 测试用例 test_content = """-----BEGIN PRIVATE KEY----- MDM5ODk4OTMzNjExM2FiYjViMGIyNDUzZjRhNGJiYTE6Cg== -----END PRIVATE KEY-----""" print(is_valid_pem(test_content)) # 输出:False(因内容非法) ``` ### 相关问题 1. 如何通过编程方式区分PKCS#1和PKCS#8格式的PEM私钥?[^4] 2. 为什么OpenSSH新版生成的私钥格式会导致传统服务认证失败?[^1][^4] 3. 如何修复PEM文件中缺失的换行符导致的解析错误?[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值