Перейти к содержимому
ecdsa.com
Python cryptographyPython: пакет cryptography

Сообщение об ошибке

cryptography.exceptions.InvalidSignature

Исключение выбрасывается без текста сообщения: трассировка стека заканчивается голым именем класса (воспроизведено на cryptography 50.0).

Python cryptography — raised by verify()

Что это означает

public_key.verify(signature, data, ...) установил, что подпись не проходит проверку для этих данных с этим ключом. Всё разобрано успешно, просто проверка не пройдена. Исключение намеренно не содержит подробностей, поэтому для диагностики приходится проверять каждую часть входных данных по отдельности: ключ, байты данных, кодирование подписи и хеш.

Почему это происходит

Как исправить

  1. 1.

    Преобразуйте подписи raw в DER

    Если подпись занимает 64 байта (P-256), перед проверкой разделите её на r и s и закодируйте заново в DER.

    python
    from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
    
    r = int.from_bytes(raw_sig[:32], "big")
    s = int.from_bytes(raw_sig[32:], "big")
    der_sig = encode_dss_signature(r, s)
    public_key.verify(der_sig, message, ec.ECDSA(hashes.SHA256()))
  2. 2.

    Используйте Prehashed для заранее вычисленных дайджестов

    Если у вас дайджест, а не само сообщение, укажите это явно, иначе библиотека захеширует ваш хеш.

    python
    from cryptography.hazmat.primitives.asymmetric import utils
    
    public_key.verify(
        der_sig,
        digest_bytes,                                    # already SHA-256(message)
        ec.ECDSA(utils.Prehashed(hashes.SHA256())),
    )
  3. 3.

    Выясните, какие входные данные неверны

    Вставьте ключ, сообщение и подпись в инструмент разбора ошибок ниже: он проверяет обычные гипотезы о несоответствии (не тот хеш, raw вместо DER, двойное хеширование, нормализация high-S, не та кривая) и называет ту, при которой ваша подпись проходит проверку.

Связанные ошибки

Открыть всю базу ошибок подписей