forked from kay-is/web3-from-zero
-
Notifications
You must be signed in to change notification settings - Fork 0
/
06-public-and-private-keys.html
295 lines (235 loc) · 10.2 KB
/
06-public-and-private-keys.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
<!DOCTYPE html>
<link rel="stylesheet" href="boilerplate/style.css" />
<title>Web3 From Zero - Lesson 6</title>
<h1>6. Public & Private Keys</h1>
<p>
I wanted to start part two of this course with crypto-wallets. Because they will be the software,
you need to install and set up for part II. But I thought the keys are only a part of the things a
crypto-wallet manages for you and the most important part. So, I think keys should have their own
lesson.
</p>
<blockquote>
This lesson won't go into the details of elliptic curve cryptography (ECC). There are better
resources to understand this topic. If you want to learn the technical details, I recommend
the free ebook <b>Practical Cryptography for Developers</b> that has
<a href="https://cryptobook.nakov.com/asymmetric-key-ciphers/elliptic-curve-cryptography-ecc">
a part that explains ECC
</a>.
</blockquote>
<h2>Security Best Practices</h2>
<p>
If I learned one thing about cryptography, it's that <b>you should never ever give away your
private key or seed phrase</b>. If you don't understand anything from the book I linked before
or written in this lesson, at least keep that small piece of know-how in mind.
</p>
<p>
This rule means you should only ever type your private key in a secure crypto-wallet app and never
in a text file on your PC or smartphone. It's too long for the usual human to remember without
much work, so for backup <b>write it down on paper</b>. This way no one who uses your computers
can read it from your hard drive.
</p>
<p>
In some countries, you might fear that the government will be after your keys, but the more likely
threat is your house burning down or water damage. So, make sure you have copies at different safe
locations.
</p>
<p>
If you need a private key for development and tests that you will hard-code in a source file, make
sure you don't use this development key for your everyday crypto dealings. This way, it's not so
bad when your key ends up on GitHub, S3, etc.
</p>
<p>
The same goes for your seed phrase, which is a way to write down a private key as a list of short
words. As a developer, you work directly with private keys, but end-users use their private key in
the form of a seed phrase when they move it around between crypto-wallets and paper.
</p>
<p>
It's also good to know that <b>you shouldn't show people your addresses and public keys without a
good reason</b>. While no one can directly steal your tokens without your private key, an attacker
can send tokens to your address for phishing. These could lead you to some web apps that try to
scam you into using your private key to do something dumb.
</p>
<h2>What are Keys?</h2>
<p>
A key, private or public, is just some kind of data. In the specific case of ECC, these two keys
are very big numbers. So big that you will store them as <code>string</code> or
<code>BigInteger</code>in JavaScript.
</p>
<figure>
<img src="images/ecc-keys.png">
<figcaption>
Figure 1: ECC Keys
</figcaption>
</figure>
<h3>Private Key</h3>
<p>
A private key for ECC is a randomly generated integer that can look something like this in hexadecimal:<br>
<code>57cfa2d774eab59998a0b87d641b504aaefeae12f244db08d77e019e6d90afb9</code>
</p>
<p>
In Ethereum and many other blockchain networks, this key must be smaller than a special prime
number.
</p>
<p>
This big prime number looks like this in hexadecimal: <br>
<code>fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f</code>
</p>
<p>
The reason why this exact prime number is used is out of the scope of this course (you can
read about it in the book I linked above). But the limit set by that prime number is important!
Not every random integer is a valid private key, and if you want to generate your own, it has to
be smaller than that prime number.
</p>
<pre>
let privateKey
do {
privateKey = generateRandomInteger()
} while(privateKey > 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn)
</pre>
<h3>Public Key</h3>
<p>
A public key for ECC is two integers that are concatenated together. Both of these integers can
have the private key length, but they aren't random. These two numbers are calculated from the
private key.
</p>
<p>
A public key can look like this:<br>
<code>0453a07319d6d7a34d1bf3363415a316c0f5cd4cb5fe49f414b1c9d7b420169b652cf466ed56ec01733a9726ee27017ad66e384eefc2d6897aa61d3157cc1273eb</code>
</p>
<p>
The function used to calculate a public key from a private key is based on a specific algorithm
and some predefined parameters. All systems interacting with the Ethereum network have to use the
same algorithm and parameters to get the same results.
</p>
<pre>
let privateKey
do {
privateKey = generateRandomInteger()
} while(privateKey > 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn)
const publicKey = generatePublicKey(privateKey)
</pre>
<h3>Seed Phrase</h3>
<p>
A seed phrase, also known as a secret recovery phrase, is a list of 12-24 short random words used
to generate one or more private keys and, in turn, public keys and addresses in the end.
</p>
<p>
A seed phrase could look like this:<br>
<code>forget wing follow flip swallow achieve correct view dinner witness hybrid proud</code>
</p>
<p>
While you can generate a private key directly, many crypto-wallet apps use a seed phrase to
generate them for you. Many people use multiple addresses, and if you're developing with Ethereum
and using it for day-to-day things, you will at least need two addresses and two private keys.
</p>
<p>
The idea of a seed phrase is that it's a random list of words, but the algorithm to generate
multiple private keys from that phrase is deterministic. This allows to generate multiple keys
from one phrase and recover all these keys from one seed phrase. Otherwise, you would have to
write down every single private key on its own.
</p>
<pre>
const seedPhrase = [
"forget", "wing", "follow",
"flip", "swallow", "achieve",
"correct", "view", "dinner",
"witness", "hybrid", "proud"
]
const keyGenerator = initKeyGenerator(seedPhrase)
const keys = []
for(let i = 0; i < 10; ++i) {
const privateKey = keyGenerator(i)
const publicKey = generatePublicKey(privateKey)
const address = keccak256(publicKey).toString().slice(0,20)
keys.push({ privateKey, publicKey, address})
}
</pre>
<br>
<p>
The downside of this is that if your seed phrase gets stolen, all private keys generated from it
are stolen too. This means everything true for your private key is also true ten-fold for your
seed phrase because it's the same as multiple private keys.
</p>
<p>
<b>Never write your seed phrase down on your PC or smartphone outside of a crypto-wallet app,
never store it in an S3 bucket, or GitHub, etc.</b> To recover your keys when you lose your
smartphone or laptop, or they break, you can write the seed phrase on a piece of paper and store
it in a safe location.
</p>
<h2>What are the Keys Used for?</h2>
<p>
So, you know what the keys are and how you should handle them, but what exactly is their purpose?
</p>
<p>
Private and public keys are used for different tasks. Their usage follows from the fact that
everyone can have your public keys, and no one should ever have your private keys.
</p>
<h3>Signing Messages with the Private Key</h3>
<p>
The private key is used mainly to sign data. Signing means you attach a signature to the data.
A signature is created with a signature algorithm that uses your private key and the data that
needs to be signed.
</p>
<p>
The idea is that the signature data can't be generated without having the private key.
</p>
<p>
A signature could look like this in its Base64 version:<br>
<code>MEQCIEamErEp0wjW2nBCwPJyMWB1UEb8UHaEFeUDko88MOs/AiB5daIS5j1stXRetBsEWbvd0TeoYsfucmADmxFUxbE2oQ==</code>
</p>
<p>
The public key is used to verify that signature. If you sign something with a private key, the
related public key, in combination with a signing algorithm, the signature, and the signed data,
will either lead to a "yes, this signature is from the correct private key" or not.
</p>
<p>
Since you are the only one who has your private keys, you are the only one who can create these
signatures. If your keys get stolen, other people can pretend they are the original owners (i. e.
you). If you lose your private key, you can't create correct signatures anymore, and systems with
your public key won't believe that you are indeed who you pretend to be.
</p>
<p>
In Figure 2, you see how the three parts interact with each other.
</p>
<figure>
<img src="images/signature.png">
<figcaption>
Figure 2: Signing and verification
</figcaption>
</figure>
<h3>Enctypting Messages with the Public Key</h3>
<p>
You learned you can use the public key to verify a signature, but that's not all it can do. The
public key can also encrypt a message that only the corresponding private key can decrypt.
</p>
<p>
If you want to use asymetric encryption to communicate privately, you have to exchange public keys.
Everyone with your public key can then send you messages that only you can read.
</p>
<p>
Figure 3 shows the simplified process. For performance reasons, the message in that picture is
usually not the actual data you want to send, but a symmetric encryption key that will be
exchanged with the private key holder and then used to encrypt/decrypt all messages flowing
between the two parties.
</p>
<figure>
<img src="images/encryption.png">
<figcaption>
Figure 3: Encryption and decryption
</figcaption>
</figure>
<h2>Conclusion</h2>
<p>
In this lesson, you learned that keys are just numbers. Very big numbers, that have specific
properties. They are often displayed in hexadecimal, which makes things a bit confusing for
beginners.
</p>
<p>
These keys are used together with ECC-based algorithms and in the case of Ethereum, with a
specific set of parameters that are the same in the whole Ethereum network to ensure, all
participants have the same results when signing and verifying data.
</p>
<p>
In <a href="07-externally-owned-accounts.html">the next lesson</a>, you will learn more about
externally owned accounts, and how they relate to the keys we discussed here.
</p>