2013-08-11 4 views
1

У меня есть приложение, которое хранит ключи ssh. Пользователь записывает свой закрытый и открытый ключ в 2 текстовых поля, и перед их сохранением мое приложение должно проверить, совпадает ли закрытый ключ с открытым ключом (с использованием pycrypto). Проверка пары RSA было достаточно легко:Проверка пары ключей DSA с pycrypto (получение значений pqg)

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.

ответ

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) имеет код для импорта ключей DSA в формате SSH:

    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) 
    
+0

Это одна кажется очень хорошо! Теперь мне нужно найти эту функцию b (char) ... –

+0

Это работает как шарм для открытого ключа, но я просто не могу понять, как заставить его работать для частного. Должны ли эти два быть в одной строке/переменной? –

+0

Строка 'ssh-dss' содержит только открытый ключ. Закрытый ключ DSA обычно находится в отдельном файле PEM. Это то, что ваши пользователи будут копировать и вставлять? Этот формат совершенно другой (и он также может быть зашифрован паролем). Текущая основная ветвь содержит код для этого. – SquareRootOfTwentyThree

Смежные вопросы