Getting started

The library has just one mandatory dependency: six. If you install python-ecdsa through pip, it should automatically install six too.

To install it you can run the following command:

pip install ecdsa

The high level API provided by the library is primarily in the keys module. There you will find the SigningKey (the class that enables handling of the private keys) and the VerifyingKey (the class that enables handling of the public keys).

To handle shared key derivation, the ECDH class is used.

Finally, in case use of custom elliptic curves is necessary, the Curve class may be needed.

Key generation

To generate a key, import the SigningKey and call the generate() function in it:

from ecdsa.keys import SigningKey

key = SigningKey.generate()

By default, that will create a key that uses the NIST P-192 curve. To select a more secure curve, like NIST P-256, import it from the ecdsa.curves or from the ecdsa module:

from ecdsa import SigningKey, NIST256p

key = SigningKey.generate(curve=NIST256p)

Private key storage and retrieval

To store a key as string or file, you can serialise it using many formats, in general we recommend the PKCS#8 PEM encoding.

If you have a SigningKey object in key and want to save it to a file like priv_key.pem you can run the following code:

with open("priv_key.pem", "wb") as f:
    f.write(key.to_pem(format="pkcs8"))

Warning

Not specifying the format=pkcs8 will create a file that uses the legacy ssleay file format which is most commonly used by applications that use OpenSSL, as that was originally the only format supported by it. For a long time though OpenSSL supports the PKCS# 8 format too.

To read that file back, you can run code like this:

from ecdsa import SigningKey

with open("priv_key.pem") as f:
    key = SigningKey.from_pem(f.read())

Tip

As the format is self-describing, the parser will automatically detect if the provided file is in the ssleay or the pkcs8 format and process it accordingly.

Public key derivation

To get the public key associated with the given private key, either call the get_verifying_key() method or access the verifying_key attribute in SigningKey directly:

from ecdsa import SigningKey, NIST256p

private_key = SigningKey.generate(curve=NIST256p)

public_key = private_key.verifying_key

Public key storage and retrieval

Similarly to private keys, public keys can be stored in files:

from ecdsa import SigningKey

private_key = SigningKey.generate()

public_key = private_key.verifying_key

with open("pub_key.pem", "wb") as f:
    f.write(public_key.to_pem())

And read from files:

from ecdsa import VerifyingKey

with open("pub_key.pem") as f:
    public_key = VerifyingKey.from_pem(f.read())

Signing

To sign a byte string stored in variable message using SigningKey in private_key, SHA-256, get a signature in the DER format and save it to a file, you can use the following code:

from hashlib import sha256
from ecdsa.util import sigencode_der

sig = private_key.sign_deterministic(
    message,
    hashfunc=sha256,
    sigencode=sigencode_der
)

with open("message.sig", "wb") as f:
    f.write(sig)

Note

As cryptographic hashes (SHA-256, SHA3-256, etc.) operate on bytes not text strings, any text needs to be serialised into bytes before it can be signed. This is because encoding of string “text” results in very different bytes when it’s encoded using UTF-8 and when it’s encoded using UCS-2.

Verifying

To verify a signature of a byte string in message using a VerifyingKey in public_key, SHA-256 and a DER signature in a message.sig file, you can use the following code:

from hashlib import sha256
from ecdsa import BadSignatureError
from ecdsa.util import sigdecode_der

with open("message.sig", "rb") as f:
    sig = f.read()

try:
    ret = public_key.verify(sig, message, sha256, sigdecode=sigdecode_der)
    assert ret
    print("Valid signature")
except BadSignatureError:
    print("Incorrect signature")