使用pycrypto验证DSA密钥对(获取pqg值)

时间:2013-08-11 14:31:03

标签: python validation ssh pycrypto dsa

我有一个存储ssh密钥的应用程序。用户将他的私钥和公钥写入2个文本框,在存储之前,我的应用程序应检查私钥是否与公钥匹配(使用pycrypto)。验证RSA对很容易:

message = 'Encrypted message'

if 'ssh-rsa' in public_key:

    public_key_container = RSA.importKey(public_key)
    private_key_container = RSA.importKey(private_key)

    encrypted_message = public_key_container.encrypt(message, 0)
    decrypted_message = private_key_container.decrypt(encrypted_message)

    if message == decrypted_message:
        return True

我找到了似乎验证DSA密钥对的代码,但我找不到如何从用户公钥和私钥中提取PQG值:

elif 'ssh-dss' in public_key:

    q = "?"
    p = "?"
    g = "?"

    pub_k = ""
    for b in bytearray(public_key, 'utf-8'):
        pub_k += str(b)

    priv_k = ""
    for b in bytearray(private_key, 'utf-8'):
        priv_k += str(b)

    params = ( long(pub_k), long(g), long(p), long(q), long(priv_k))

    key = DSA.construct(params)

    if key.verify(message, key.sign(message,3)):
        return True

请不要提示我使用像ssh-keygen这样的函数从私钥生成公钥。我知道这个方法,我想用pycrypto来做。

1 个答案:

答案 0 :(得分:2)

PyCrypto的当前代码库包含一些您可能感兴趣的代码:

  • 一个开放式拉取请求(link)在构建时验证RSA和DSA。测试比上面显示的测试更强大,即使恶意用户仍然可以制作弱密钥并让它通过。 对于DSA密钥,它是这样的:

    # Modulus must be prime
    fmt_error = not isPrime(key.p)
    # Verify Lagrange's theorem for sub-group 
    fmt_error |= ((key.p-1) % key.q)!=0 
    fmt_error |= key.g<=1 or key.g>=key.p
    fmt_error |= pow(key.g, key.q, key.p)!=1 
    # Public key
    fmt_error |= key.y<=0 or key.y>=key.p 
    if hasattr(key, 'x'):
        fmt_error |= key.x<=0 or key.x>=key.q 
        fmt_error |= pow(key.g, key.x, key.p)!=key.y
    
  • 主分支(请参阅lib/Crypto/PublicKey/DSA.py)包含以SSH格式导入DSA密钥的代码:

    if extern_key.startswith(b('ssh-dss ')):
        # This is probably a public OpenSSH key
        keystring = binascii.a2b_base64(extern_key.split(b(' '))[1])
        keyparts = []
        while len(keystring) > 4:
            length = struct.unpack(">I", keystring[:4])[0]
            keyparts.append(keystring[4:4 + length])
            keystring = keystring[4 + length:]
        if keyparts[0] == b("ssh-dss"):
            tup = [bytes_to_long(keyparts[x]) for x in (4, 3, 1, 2)]
            return self.construct(tup)