@@ -6,6 +6,12 @@ The library has just one mandatory dependency: ``six``.
66If you install ``python-ecdsa `` through pip, it should automatically
77install ``six `` too.
88
9+ To install it you can run the following command:
10+
11+ .. code :: bash
12+
13+ pip install ecdsa
14+
915 The high level API provided by the library is primarily in the
1016:py:class: `~ecdsa.keys ` module.
1117There you will find the :py:class: `~ecdsa.keys.SigningKey ` (the class
@@ -19,3 +25,154 @@ is used.
1925Finally, in case use of custom elliptic curves is necessary, the
2026:py:class: `~ecdsa.curves.Curve ` class may be needed.
2127
28+ Key generation
29+ ==============
30+
31+ To generate a key, import the :py:class: `~ecdsa.keys.SigningKey ` and
32+ call the :py:func: `~ecdsa.keys.SigningKey.generate ` function in it:
33+
34+ .. code :: python
35+
36+ from ecdsa.keys import SigningKey
37+
38+ key = SigningKey.generate()
39+
40+ By default, that will create a key that uses the NIST P-192 curve. To
41+ select a more secure curve, like NIST P-256, import it from the
42+ :py:mod: `ecdsa.curves ` or from the :py:mod: `ecdsa ` module:
43+
44+ .. code :: python
45+
46+ from ecdsa import SigningKey, NIST256p
47+
48+ key = SigningKey.generate(curve = NIST256p)
49+
50+ Private key storage and retrieval
51+ =================================
52+
53+ To store a key as string or file, you can serialise it using many formats,
54+ in general we recommend the PKCS#8 PEM encoding.
55+
56+ If you have a :py:class: `~ecdsa.keys.SigningKey ` object in ``key `` and
57+ want to save it to a file like ``priv_key.pem `` you can run the following
58+ code:
59+
60+ .. code :: python
61+
62+ with open (" priv_key.pem" , " wb" ) as f:
63+ f.write(key.to_pem(format = " pkcs8" ))
64+
65+ .. warning ::
66+
67+ Not specifying the ``format=pkcs8 `` will create a file that uses the legacy
68+ ``ssleay `` file format which is most commonly used by applications
69+ that use OpenSSL, as that was originally the only format supported by it.
70+ For a long time though OpenSSL supports the PKCS# 8 format too.
71+
72+ To read that file back, you can run code like this:
73+
74+ .. code :: python
75+
76+ from ecdsa import SigningKey
77+
78+ with open (" priv_key.pem" ) as f:
79+ key = SigningKey.from_pem(f.read())
80+
81+ .. tip ::
82+
83+ As the format is self-describing, the parser will automatically detect
84+ if the provided file is in the ``ssleay `` or the ``pkcs8 `` format
85+ and process it accordingly.
86+
87+ Public key derivation
88+ =====================
89+
90+ To get the public key associated with the given private key, either
91+ call the :py:func: `~ecdsa.keys.SigningKey.get_verifying_key ` method or
92+ access the ``verifying_key `` attribute in
93+ :py:class: `~ecdsa.keys.SigningKey ` directly:
94+
95+ .. code :: python
96+
97+ from ecdsa import SigningKey, NIST256p
98+
99+ private_key = SigningKey.generate(curve = NIST256p)
100+
101+ public_key = private_key.verifying_key
102+
103+ Public key storage and retrieval
104+ ================================
105+
106+ Similarly to private keys, public keys can be stored in files:
107+
108+ .. code :: python
109+
110+ from ecdsa import SigningKey
111+
112+ private_key = SigningKey.generate()
113+
114+ public_key = private_key.verifying_key
115+
116+ with open (" pub_key.pem" , " wb" ) as f:
117+ f.write(public_key.to_pem())
118+
119+ And read from files:
120+
121+ .. code :: python
122+
123+ from ecdsa import VerifyingKey
124+
125+ with open (" pub_key.pem" ) as f:
126+ public_key = VerifyingKey.from_pem(f.read())
127+
128+ Signing
129+ =======
130+
131+ To sign a byte string stored in variable ``message `` using SigningKey in
132+ ``private_key ``, SHA-256, get a signature in the DER format and save it to a
133+ file, you can use the following code:
134+
135+ .. code :: python
136+
137+ from hashlib import sha256
138+ from ecdsa.util import sigencode_der
139+
140+ sig = private_key.sign_deterministic(
141+ message,
142+ hashfunc = sha256,
143+ sigencode = sigencode_der
144+ )
145+
146+ with open (" message.sig" , " wb" ) as f:
147+ f.write(sig)
148+
149+ .. note ::
150+
151+ As cryptographic hashes (SHA-256, SHA3-256, etc.) operate on *bytes * not
152+ text strings, any text needs to be serialised into *bytes * before it can
153+ be signed. This is because encoding of string "text" results in very
154+ different bytes when it's encoded using UTF-8 and when it's encoded using
155+ UCS-2.
156+
157+ Verifying
158+ =========
159+
160+ To verify a signature of a byte string in ``message `` using a VerifyingKey
161+ in ``public_key ``, SHA-256 and a DER signature in a ``message.sig `` file,
162+ you can use the following code:
163+
164+ .. code :: python
165+
166+ from hashlib import sha256
167+ from ecdsa import BadSignatureError
168+ from ecdsa.util import sigdecode_der
169+
170+ with open (" message.sig" , " rb" ) as f:
171+ sig = f.read()
172+
173+ try :
174+ ret = public_key.verify(sig, message, sha256, sigdecode = sigdecode_der)
175+ assert ret
176+ print (" Valid signature" )
177+ except BadSignatureError:
178+ print (" Incorrect signature" )
0 commit comments