仅使用服务器指纹即可使用pysftp和Python 3连接到SFTP服务器

发布于 2021-01-29 14:59:39

我处于一种奇怪的情况下,我需要第一次连接到SFTP服务器,但似乎找不到找到访问该服务器的已知主机条目的方法。如果我可以连接很好说:

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):

但显然,这会让您在中间攻击时对男人敞开怀抱。所以我尝试连接:

cnopts = pysftp.CnOpts(knownhosts='config/known_host')
cnopts.hostkeys = None

with pysftp.Connection(host, username=username, password=password, cnopts=cnopts) as sftp:

而且我得到各种错误消息。最近的是:

paramiko.hostkeys.InvalidHostKey

问题是我没有主机密钥,因为我是第一次连接。我试图从其他连接中获取密钥。我使用WinSCP,但是它将密钥存储在注册表文件中,并且格式与known_host不同。我试图使用ssh-
keyscan用PuTTY来获取它,但是服务器甚至不允许我启动终端会话。我们不是盒子的主人,托管服务提供商不太可能提供我们所需的东西。

我不走运吗?我应该继续绕过按键检查吗?

关注者
0
被浏览
113
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    可以在Python中找到解决方案-pysftp / paramiko-
    使用其指纹验证主机密钥,
    但是我必须对其进行一些改动才能使用Python 3。

    import hashlib as hl
    
    
    def trim_fingerprint(fingerprint):
        #if fingerprint.startswith('ecdsa-sha2-nistp384 384 '):
            #return fingerprint[len('ecdsa-sha2-nistp384 384 '):]
        return fingerprint
    
    
    def clean_fingerprint(fingerprint):
        #return trim_fingerprint(fingerprint).replace(':', '')
        return trim_fingerprint(fingerprint)
    
    class FingerprintKey:
    
        def __init__(self, fingerprint):
            self.fingerprint = clean_fingerprint(fingerprint)
    
        def compare(self, other):
            if callable(getattr(other, "get_fingerprint", None)):
                return other.get_fingerprint() == self.fingerprint
            elif clean_fingerprint(other) == self.get_fingerprint():
                return True
            #elif hl.md5(other).digest().encode('hex') == self.fingerprint:
            #The line below is required for Python 3.  Above is Python 2.
            elif hl.md5(other).hexdigest() == self.fingerprint:
                return True
            else:
                return False
    
        def __cmp__(self, other):
            return self.compare(other)
    
        def __contains__(self, other):
            return self.compare(other)
    
        def __eq__(self, other):
            return self.compare(other)
    
        def __ne__(self, other):
            return not self.compare(other)
    
        def get_fingerprint(self):
            return self.fingerprint
    
        def get_name(self):
            return u'ecdsa-sha2-nistp384'
    
        def asbytes(self):
             # Note: This returns itself.
             #   That way when comparisons are done to asbytes return value,
             #   this class can handle the comparison.
            return self
    

    我必须手动从指纹中删除任何“:”,因为它从未允许脚本执行此操作。

    用法:

    options = pysftp.CnOpts()
    options.hostkeys.clear()
    options.hostkeys.add('www.sample.com', u'ecdsa-sha2-nistp384 384 ', AuthOnFingerPrint.FingerprintKey(serverkey))
    

    其中serverkey是指纹。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看