@@ -6,6 +6,12 @@ The library has just one mandatory dependency: ``six``.
6
6
If you install ``python-ecdsa `` through pip, it should automatically
7
7
install ``six `` too.
8
8
9
+ To install it you can run the following command:
10
+
11
+ .. code :: bash
12
+
13
+ pip install ecdsa
14
+
9
15
The high level API provided by the library is primarily in the
10
16
:py:class: `~ecdsa.keys ` module.
11
17
There you will find the :py:class: `~ecdsa.keys.SigningKey ` (the class
@@ -19,3 +25,154 @@ is used.
19
25
Finally, in case use of custom elliptic curves is necessary, the
20
26
:py:class: `~ecdsa.curves.Curve ` class may be needed.
21
27
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