【问题标题】:paramiko: why cannot use explicitly specified key?paramiko:为什么不能使用明确指定的密钥?
【发布时间】:2021-12-28 23:49:55
【问题描述】:

我正在使用 paramiko (v2.7.1) 连接到具有授权密钥的主机。当我没有明确传递密钥时,我可以连接。但是,当我用key_filename 传递它时,我得到一个错误:

ValueError: ('Invalid private key', [_OpenSSLErrorWithText(code=67764350, lib=4, func=160, reason=126, reason_text=b'error:040A007E:rsa routines:RSA_check_key_ex:iqmp not inverse of q')])

我检查了路径是否正确,并且密钥确实与远程主机上的公钥匹配(以防我们使用其他方法登录)。

我也可以直接连接 w/ssh,无论是 w/o 显式密钥还是 with。当我没有明确指定密钥时, ssh -vvv 会打印到私钥的匹配路径。密钥使用rsa-sha2-512 编码。最后,当我从 ~/.ssh 中移动密钥并清除身份验证缓存时,我无法再连接 ssh,证明它绝对是让我进入的密钥。

还有什么我可以做的吗?我目前正在手动测试一个脚本,该脚本旨在在默认位置未安装密钥的情况下运行?

我的代码:

vm = paramiko.SSHClient()
vm.set_missing_host_key_policy(paramiko.AutoAddPolicy())
vm.connect(
    DEST_ADDR, username=DEST_USER, key_filename=DEST_KEY_FILE, 
    )

代码不能按原样工作,但如果我注释掉key_filename 参数,它就可以工作。键的访问方式是否因查找方式而异?

追溯:

ValueError                                Traceback (most recent call last)
<ipython-input-25-57a83e5f85d1> in <module>
      3 # vm.connect(
      4 #     JUMP_ADDR, username=JUMP_USER, key_filename=JUMP_KEY_FILE)
----> 5 vm.connect(
      6     DEST_ADDR, username=DEST_USER, key_filename=DEST_KEY_FILE,
      7     ) # sock=vmchannel)

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/client.py in connect(self, hostname, port, username, password, pkey, key_filename, timeout, allow_agent, look_for_keys, compress, sock, gss_auth, gss_kex, gss_deleg_creds, gss_host, banner_timeout, auth_timeout, gss_trust_dns, passphrase, disabled_algorithms)
    433             key_filenames = key_filename
    434 
--> 435         self._auth(
    436             username,
    437             password,

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/client.py in _auth(self, username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host, passphrase)
    674                 for pkey_class in (RSAKey, DSSKey, ECDSAKey, Ed25519Key):
    675                     try:
--> 676                         key = self._key_from_filepath(
    677                             key_filename, pkey_class, passphrase
    678                         )

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/client.py in _key_from_filepath(self, filename, klass, password)
    584             cert_path = filename + cert_suffix
    585         # Blindly try the key path; if no private key, nothing will work.
--> 586         key = klass.from_private_key_file(key_path, password)
    587         # TODO: change this to 'Loading' instead of 'Trying' sometime; probably
    588         # when #387 is released, since this is a critical log message users are

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/pkey.py in from_private_key_file(cls, filename, password)
    233         :raises: `.SSHException` -- if the key file is invalid
    234         """
--> 235         key = cls(filename=filename, password=password)
    236         return key
    237 

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/rsakey.py in __init__(self, msg, data, filename, password, key, file_obj)
     53             return
     54         if filename is not None:
---> 55             self._from_private_key_file(filename, password)
     56             return
     57         if (msg is None) and (data is not None):

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/rsakey.py in _from_private_key_file(self, filename, password)
    174     def _from_private_key_file(self, filename, password):
    175         data = self._read_private_key_file("RSA", filename, password)
--> 176         self._decode_key(data)
    177 
    178     def _from_private_key(self, file_obj, password):

/usr/local/share/anaconda3/lib/python3.8/site-packages/paramiko/rsakey.py in _decode_key(self, data)
    192             n, e, d, iqmp, q, p = self._uint32_cstruct_unpack(data, "iiiiii")
    193             public_numbers = rsa.RSAPublicNumbers(e=e, n=n)
--> 194             key = rsa.RSAPrivateNumbers(
    195                 p=p,
    196                 q=q,

/usr/local/share/anaconda3/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py in private_key(self, backend)
    365     def private_key(self, backend=None) -> RSAPrivateKey:
    366         backend = _get_backend(backend)
--> 367         return backend.load_rsa_private_numbers(self)
    368 
    369     def __eq__(self, other):

/usr/local/share/anaconda3/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py in load_rsa_private_numbers(self, numbers)
    600         evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata)
    601 
--> 602         return _RSAPrivateKey(self, rsa_cdata, evp_pkey)
    603 
    604     def load_rsa_public_numbers(self, numbers):

/usr/local/share/anaconda3/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/rsa.py in __init__(self, backend, rsa_cdata, evp_pkey)
    387         if res != 1:
    388             errors = backend._consume_errors_with_text()
--> 389             raise ValueError("Invalid private key", errors)
    390 
    391         # Blinding is on by default in many versions of OpenSSL, but let's

ValueError: ('Invalid private key', [_OpenSSLErrorWithText(code=67764350, lib=4, func=160, reason=126, reason_text=b'error:040A007E:rsa routines:RSA_check_key_ex:iqmp not inverse of q')])

参考:https://github.com/paramiko/paramiko/issues/1929

【问题讨论】:

  • 当我没有明确传递密钥时,我可以连接...听起来您无需身份验证即可连接,如果是这样,那就是一个安全漏洞。错误消息非常清楚,与连接尝试无关。您的私钥文件已损坏,或者至少错误消息是这样说的。实际上,文件的格式可能与预期不同。
  • no -- 见 ssh -vvv -- 它明确列出了密钥并说它的签名sign_and_send_pubkey: signing using rsa-sha2-512 这是明确指定密钥的情况,也不是。 ...是的:我希望 paramiko 以不同的方式查找密钥,并且如果明确指定,对格式(或尝试错误的编码?)更加挑剔.... and 当我使用 paramiko w /o 显式键我得到INFO:paramiko.transport:Authentication (publickey) successful! -- 没有那么多细节,但似乎使用了一个键。
  • 错误信息清晰无误。也许只是为了测试尝试使用不同的键。
  • 确实——而且错了!当我传递一个无效的密钥(启用调试)时,它使用该密钥失败,但随后在回退尝试中成功。 (不确定是否有关闭回退的选项。)

标签: python ssh paramiko


【解决方案1】:

这是 paramiko 2.7.1 的问题——通过安装 2.8.0 解决

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多