ECDSA Cryptographic Signature Library
ecdsa is a pure Python implementation of Elliptic Curve Cryptography (ECC) supporting ECDSA (Elliptic Curve Digital Signature Algorithm), EdDSA (Edwards-curve Digital Signature Algorithm), and ECDH (Elliptic Curve Diffie-Hellman). It is actively maintained with several releases per year, providing a robust solution for digital signatures in Python applications. The current version is 0.19.2.
Warnings
- breaking CVE-2024-23342 (Minerva Timing Attack) affects P-256 curves in versions 0.18.0 and prior. This side-channel vulnerability allows attackers to leak the internal nonce via timing measurements, potentially leading to private key discovery. The maintainers consider side-channel attacks out of scope, and no fix is planned for this pure-Python implementation.
- breaking CVE-2026-33936 fixed a DER parsing issue where truncated buffers were not detected, which could lead to unexpected exceptions in functions like `SigningKey.from_der()` when parsing malformed data.
- gotcha When serializing keys using `to_pem()` or `to_der()`, in versions 0.16.0 and later, it is recommended to explicitly set `format="pkcs8"`. Not doing so will default to the legacy 'ssleay' format, which may not be the desired standard for modern applications or interoperability.
- deprecated Official support for Python 3.3 and 3.4 was dropped starting from version 0.19.0 due to CI environment challenges.
- gotcha The `to_string()` method, inherited from Python 2 naming conventions, actually returns `bytes` objects, not Python `str`.
- gotcha When deserializing keys using `SigningKey.from_string(s, curve)` or `VerifyingKey.from_string(s, curve)`, the `curve` parameter *must* be explicitly provided as the short string format does not embed curve information. If the wrong curve is provided, verification will fail or lead to incorrect keys.
Install
-
pip install ecdsa
Imports
- SigningKey
from ecdsa import SigningKey
- VerifyingKey
from ecdsa import VerifyingKey
- NIST256p
from ecdsa import NIST256p
- SECP256k1
from ecdsa import SECP256k1
Quickstart
import hashlib
from ecdsa import SigningKey, NIST256p, VerifyingKey
# 1. Generate a private key using the NIST256p curve
sk = SigningKey.generate(curve=NIST256p)
print("Private Key (hex):", sk.to_string().hex())
# 2. Derive the public key
vk = sk.get_verifying_key()
print("Public Key (hex):", vk.to_string().hex())
# 3. Message to sign (must be bytes)
message = b"This is a test message to be signed."
# Hash the message before signing
message_hash = hashlib.sha256(message).digest()
# 4. Sign the message hash
signature = sk.sign_digest(message_hash)
print("Signature (hex):", signature.hex())
# 5. Verify the signature
try:
assert vk.verify_digest(signature, message_hash) == True
print("Signature is valid.")
except Exception as e:
print(f"Signature verification failed: {e}")