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

时间:2017-12-01 03:30:04

标签: python ssh pysftp

我是一个奇怪的情况,我需要第一次连接到SFTP服务器,但我似乎无法找到一种方法来访问服务器的已知主机条目如果我说:我可以连接好:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="foo">The time is 8:00</span>

但显然这让你在中间攻击中对人开放。所以我尝试连接:

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

我得到各种错误信息。最近的一个是:

  

paramiko.hostkeys.InvalidHostKey

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

我运气不好吗?我应该继续并绕过检查钥匙吗?

1 个答案:

答案 0 :(得分:2)

解决方案可以在Python - pysftp / paramiko - Verify host key using its fingerprint找到,但我不得不改变它以使用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

我不得不手动删除任何&#34;:&#34;从指纹,因为它只是从来没有工作允许脚本这样做。

用法:

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

其中serverkey是指纹。