Подпишите сообщение с помощью DSA с библиотекой pyOpenSSL

Это мой первый вопрос здесь, потому что я не нашел решения для этого. Надеюсь, у кого-то есть ответ на этот вопрос.

Я пытаюсь подписать и проверить сообщение с помощью DSA (алгоритма цифровой подписи) и оболочки pyOpenSSL.

Я создал пример ниже:

from OpenSSL.crypto import TYPE_DSA, Error, PKey
from OpenSSL.crypto import FILETYPE_PEM, sign
from Crypto.Hash import SHA
key = PKey()
key.generate_key(TYPE_DSA, 1024)
message = "abc"
digest = SHA.new(message).digest()
data_to_sign = base64.b64encode(digest)
signature = sign(key, data_to_sign, 'sha1')

После запуска этого фрагмента кода я получу следующий результат:

OpenSSL.crypto.Error: [('digital envelope routines', 'EVP_SignFinal', 'wrong public key type')]

person Minh Trang Nguyen    schedule 16.01.2015    source источник
comment
EVP_Sign* и EVP_Verify* — старые интерфейсы. Вы должны использовать новый механизм OpenSSL: EVP_DigestSign* и EVP_DigestVerify*.   -  person jww    schedule 17.01.2015
comment
DSA удаляется из TLS 1.3. Судя по всему, этим никто не пользуется. Используйте RSA и ECDSA. TLS 1.3 может включать ed25519.   -  person jww    schedule 17.01.2015


Ответы (1)


Я нашел решение, но использовал другую библиотеку Python. Библиотека OpenSSL, которую я использую на своем Mac, у меня не работает. Я использую 4096-битный ключ, и библиотека его не поддерживает. В моей Linux-системе работал следующий скрипт.

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import interfaces
from cryptography.hazmat.primitives.serialization import load_pem_private_key, load_pem_public_key
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature

pem_data = contents = open('./pri.pem').read()
pem_public_data = contents = open('./pub.pem').read()
key = load_pem_private_key(pem_data, password=None, backend=default_backend())
if isinstance(key, interfaces.DSAPrivateKey):
    msg = b"abc"
    signer = key.signer(hashes.SHA1())
    signer.update(msg)
    signature = signer.finalize()
    public_key = load_pem_public_key(pem_public_data, backend=default_backend())
    verifier = public_key.verifier(signature, hashes.SHA1())
    verifier.update(msg)
    try:
        verifier.verify()
        print 'Signature is valid'
    except InvalidSignature:
        print 'InvalidSignature'
person Minh Trang Nguyen    schedule 17.01.2015
comment
Спасибо, Мин, после долгих поисков это был самый полезный пост о подписании закрытым ключом DSA сообщения в python. - person Hassek; 05.06.2015