· 6 years ago · Aug 13, 2019, 04:40 AM
1<html>
2<head>
3<title>TweetNaCl-js based crypto</title>
4<script src='nacl-fast.min.js'></script>
5<script src='nacl-util.min.js'></script>
6<script>
7 function sbox_getpwd() {
8 var key = document.getElementById('secretbox-password').value;
9 key = nacl.util.decodeUTF8(key);
10 key = nacl.hash(key);
11 var newkey = new Uint8Array(nacl.secretbox.keyLength);
12 for (i = 0; i < nacl.secretbox.keyLength; i++) newkey[i]=key[i];
13 return newkey;
14 };
15
16 function sbox_encode() {
17 var msg = document.getElementById('secretbox-decoded').value;
18 var key = sbox_getpwd();
19 var nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
20
21 msg = nacl.util.decodeUTF8(msg);
22 var result = nacl.secretbox(msg, nonce, key);
23 document.getElementById('secretbox-encoded').value = nacl.util.encodeBase64(result) + ',' + nacl.util.encodeBase64(nonce);
24 };
25
26 function sbox_decode() {
27 var msgarr = document.getElementById('secretbox-encoded').value.split(',');
28 var msg = nacl.util.decodeBase64(msgarr[0]);
29 var nonce = nacl.util.decodeBase64(msgarr[1]);
30 var key = sbox_getpwd();
31 var result = nacl.secretbox.open(msg, nonce, key);
32 document.getElementById('secretbox-decoded').value = nacl.util.encodeUTF8(result);
33 };
34
35 function sbox_genpwd() {
36 document.getElementById('secretbox-password').value = nacl.util.encodeBase64(nacl.randomBytes(32));
37 };
38
39 function genkeypair() {
40 var keypair = nacl.box.keyPair();
41 document.getElementById('box-private-key').value = nacl.util.encodeBase64(keypair.secretKey);
42 document.getElementById('box-public-key').value = nacl.util.encodeBase64(keypair.publicKey);
43 };
44
45 function genpubkey() {
46 var secretkey = document.getElementById('box-private-key').value;
47 secretkey = nacl.util.decodeBase64(secretkey);
48 document.getElementById('box-public-key').value = nacl.util.encodeBase64(nacl.box.keyPair.fromSecretKey(secretkey).publicKey);
49 };
50
51 function box_encode() {
52 var msg = document.getElementById('box-decoded').value;
53 var mySecretKey = document.getElementById('box-private-key').value;
54 var nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
55 var theirPublicKey = document.getElementById('box-their-key').value;
56
57 msg = nacl.util.decodeUTF8(msg);
58 mySecretKey = nacl.util.decodeBase64(mySecretKey);
59 theirPublicKey = nacl.util.decodeBase64(theirPublicKey);
60
61 var result = nacl.box(msg, nonce, theirPublicKey, mySecretKey);
62 result = nacl.util.encodeBase64(result);
63 document.getElementById('box-encoded').value = result +','+nacl.util.encodeBase64(nonce);
64 };
65
66 function box_decode() {
67 var msgarr = document.getElementById('box-encoded').value.split(',');
68 var msg = msgarr[0];
69 var mySecretKey = document.getElementById('box-private-key').value;
70 var nonce = msgarr[1];
71 var theirPublicKey = document.getElementById('box-their-key').value;
72
73 msg = nacl.util.decodeBase64(msg);
74 nonce = nacl.util.decodeBase64(nonce);
75 mySecretKey = nacl.util.decodeBase64(mySecretKey);
76 theirPublicKey = nacl.util.decodeBase64(theirPublicKey);
77
78 var result = nacl.box.open(msg, nonce, theirPublicKey, mySecretKey);
79 result = nacl.util.encodeUTF8(result);
80 document.getElementById('box-decoded').value = result;
81 };
82
83 function sealedbox_encode() {
84 var msg = document.getElementById('box-decoded').value;
85 var theirPublicKey = document.getElementById('box-their-key').value;
86
87 msg = nacl.util.decodeUTF8(msg);
88 theirPublicKey = nacl.util.decodeBase64(theirPublicKey);
89
90 var result = sealedBox.seal(msg, theirPublicKey);
91 result = nacl.util.encodeBase64(result);
92 document.getElementById('box-encoded').value = result;
93 };
94
95 function sealedbox_decode() {
96 var msg = document.getElementById('box-encoded').value;
97 msg = nacl.util.decodeBase64(msg);
98
99 var mySecretKey = document.getElementById('box-private-key').value;
100 mySecretKey = nacl.util.decodeBase64(mySecretKey);
101 var myPublicKey = nacl.box.keyPair.fromSecretKey(mySecretKey).publicKey;
102
103 var result = sealedBox.open(msg, myPublicKey, mySecretKey);
104
105 result = nacl.util.encodeUTF8(result);
106 document.getElementById('box-decoded').value = result;
107
108 };
109
110 function genkeypair_sign() {
111 var keypair = nacl.sign.keyPair();
112 document.getElementById('sign-private-key').value = nacl.util.encodeBase64(keypair.secretKey);
113 document.getElementById('sign-public-key').value = nacl.util.encodeBase64(keypair.publicKey);
114 };
115
116 function genpubkey_sign() {
117 var secretkey = document.getElementById('sign-private-key').value;
118 secretkey = nacl.util.decodeBase64(secretkey);
119 document.getElementById('sign-public-key').value = nacl.util.encodeBase64(nacl.sign.keyPair.fromSecretKey(secretkey).publicKey);
120 };
121
122 function sign() {
123 var msg = document.getElementById('sign-msg').value;
124 var mySecretKey = document.getElementById('sign-private-key').value;
125
126 msg = nacl.util.decodeUTF8(msg);
127 mySecretKey = nacl.util.decodeBase64(mySecretKey);
128
129
130 var result = nacl.sign.detached(msg, mySecretKey);
131 result = nacl.util.encodeBase64(result);
132 document.getElementById('signed-msg').value = result;
133 };
134
135 function verify() {
136 var msg = document.getElementById('sign-msg').value;
137 var signature = document.getElementById('signed-msg').value;
138 var theirPublicKey = document.getElementById('signer-external-public-key').value;
139
140 msg = nacl.util.decodeUTF8(msg);
141 signature = nacl.util.decodeBase64(signature);
142 theirPublicKey = nacl.util.decodeBase64(theirPublicKey);
143
144
145 var result = nacl.sign.detached.verify(msg, signature, theirPublicKey);
146 if (result) {
147 document.getElementById('verify-result').innerHTML = "Ok!";
148 } else {
149 document.getElementById('verify-result').innerHTML = "FAILED";
150 };
151 };
152
153 //https://stackoverflow.com/questions/36280818/how-to-convert-file-to-base64-in-javascript
154 function getBase64(file) {
155 var reader = new FileReader();
156 reader.readAsDataURL(file);
157 reader.onload = function () {
158 document.getElementById('file-contents').value = reader.result;
159 console.log(reader.result);
160 };
161 reader.onerror = function (error) {
162 console.log('Error: ', error);
163 };
164 };
165
166 function file_to_b64() {
167 var files = document.getElementById('file').files;
168 if (files.length > 0) {
169 getBase64(files[0]);
170 };
171 };
172
173 function save_file() {
174 var filecontent = document.getElementById('file-contents').value;
175 document.getElementById('file-save').setAttribute("href", filecontent);
176 document.getElementById('file-save').setAttribute("download", new Date().getTime());
177 };
178
179 function seal2_encode() {
180 var msg = document.getElementById('box-decoded').value;
181 var theirPublicKey = document.getElementById('box-their-key').value;
182 var nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
183
184 msg = nacl.util.decodeUTF8(msg);
185 theirPublicKey = nacl.util.decodeBase64(theirPublicKey);
186
187 var tempKeys = nacl.box.keyPair();
188
189 var result = nacl.box(msg, nonce, theirPublicKey, tempKeys.secretKey);
190 result = nacl.util.encodeBase64(result);
191 document.getElementById('box-encoded').value = result +','+nacl.util.encodeBase64(nonce) +','+nacl.util.encodeBase64(tempKeys.publicKey);
192 };
193
194 function seal2_decode() {
195 var msgarr = document.getElementById('box-encoded').value.split(',');
196 var msg = msgarr[0];
197 var mySecretKey = document.getElementById('box-private-key').value;
198 var nonce = msgarr[1];
199 var theirPublicKey = msgarr[2];
200
201 msg = nacl.util.decodeBase64(msg);
202 nonce = nacl.util.decodeBase64(nonce);
203 mySecretKey = nacl.util.decodeBase64(mySecretKey);
204 theirPublicKey = nacl.util.decodeBase64(theirPublicKey);
205
206 var result = nacl.box.open(msg, nonce, theirPublicKey, mySecretKey);
207 result = nacl.util.encodeUTF8(result);
208 document.getElementById('box-decoded').value = result;
209 };
210
211</script>
212</head>
213<body style="margin-left: 50px;">
214
215<p>This is standalone version that can work offline if <b>nacl-fast.min.js</b> and <b>nacl-util.min.js</b> are present in the same folder.</p>
216
217<h1>File <-> Base64</h1>
218<p><input type="file" id="file" /></p>
219<p><input type="button" value="Output B64" onclick="file_to_b64();" /></p>
220<p><textarea id="file-contents"></textarea></p>
221<p><a id="file-save" href="#" onclick="save_file();">Save file</a></p>
222
223
224<h1>Secretbox</h1>
225<p>"Secret key encryption (also called symmetric key encryption) is analogous to a safe. You can store something secret through it and anyone who has the key can open it and view the contents."</p>
226<p style="color: red;">Note: passwords are not hashed securely. Use strong passwords.</p>
227<p>Decoded message<textarea id="secretbox-decoded"></textarea></p>
228<p>Password<textarea id="secretbox-password"></textarea></p>
229<p><input type="button" value="Encode" onclick="sbox_encode();"/>
230<input type="button" value="Decode" onclick="sbox_decode();"/>
231<input type="button" value="Random password" onclick="sbox_genpwd();"/></p>
232<p>Encoded message <textarea id="secretbox-encoded"></textarea></p>
233
234<h1>Asymmetric encryption</h1>
235
236<p>"Imagine Alice wants something valuable shipped to her. Because it’s valuable, she wants to make sure it arrives securely (i.e. hasn’t been opened or tampered with) and that it’s not a forgery (i.e. it’s actually from the sender she’s expecting it to be from and nobody’s pulling the old switcheroo).</p>
237<p>One way she can do this is by providing the sender (let’s call him Bob) with a high-security box of her choosing. She provides Bob with this box, and something else: a padlock, but a padlock without a key. Alice is keeping that key all to herself. Bob can put items in the box then put the padlock onto it. But once the padlock snaps shut, the box cannot be opened by anyone who doesn’t have Alice’s private key.</p>
238<p>Here’s the twist though: Bob also puts a padlock onto the box. This padlock uses a key Bob has published to the world, such that if you have one of Bob’s keys, you know a box came from him because Bob’s keys will open Bob’s padlocks (let’s imagine a world where padlocks cannot be forged even if you know the key). Bob then sends the box to Alice.</p>
239<p>"In order for Alice to open the box, she needs two keys: her private key that opens her own padlock, and Bob’s well-known key. If Bob’s key doesn’t open the second padlock, then Alice knows that this is not the box she was expecting from Bob, it’s a forgery.</p>
240<p>This bidirectional guarantee around identity is known as mutual authentication."</p>
241
242<h2>Sealed Box</h2>
243
244<p>"The SealedBox <...> encrypts messages addressed to a specified key-pair by using ephemeral sender’s keypairs, which will be discarded just after encrypting a single plaintext message.</p>
245<p>This kind of construction allows sending messages, which only the recipient can decrypt without providing any kind of cryptographic proof of sender’s authorship.</p>
246<p>By design, the recipient will have no means to trace the ciphertext to a known author, since the sending keypair itself is not bound to any sender’s identity, and the sender herself will not be able to decrypt the ciphertext she just created, since the private part of the key cannot be recovered after use."</p>
247
248
249
250<p>Decoded message<textarea id="box-decoded"></textarea></p>
251<p>Your private key<textarea id="box-private-key"></textarea><input type="button" value="Generate new" onclick="genkeypair();" /> Your public key <textarea id="box-public-key" disabled></textarea><input type="button" value="Generate from private" onclick="genpubkey();" /> </p>
252
253<p>Their public key<textarea id="box-their-key"></textarea></p>
254<p>
255 <input type="button" value="Encode bidirectional" onclick="box_encode();"/>
256 <input type="button" value="Decode bidirectional" onclick="box_decode();"/>
257 <input type="button" value="Encode SealedBox (req only their key)" onclick="seal2_encode();"/>
258 <input type="button" value="Decode SealedBox (req only private key)" onclick="seal2_decode();"/>
259</p>
260<p>Encoded message<textarea id="box-encoded"></textarea></p>
261
262<h1>Digital signatures</h1>
263<p>"You can use a digital signature for many of the same reasons that you might sign a paper document. A valid digital signature gives a recipient reason to believe that the message was created by a known sender such that they cannot deny sending it (authentication and non-repudiation) and that the message was not altered in transit (integrity).</p>
264
265<p>Digital signatures allow you to publish a public key, and then you can use your private signing key to sign messages. Others who have your public key can then use it to validate that your messages are actually authentic."<p>
266
267<h4>Message</h4><p><textarea id="sign-msg"></textarea></p>
268<p>Your private key<textarea id="sign-private-key"></textarea><input type="button" value="Generate new" onclick="genkeypair_sign();" /> Your public key <textarea id="sign-public-key" disabled></textarea><input type="button" value="Generate from private" onclick="genpubkey_sign();" /> </p>
269
270<input type="button" value="Sign" onclick="sign();"/>
271<h4>Signature</h4><p><textarea id="signed-msg"></textarea></p>
272<p>Signer's public key<textarea id="signer-external-public-key"></textarea>
273<input type="button" value="Verify" onclick="verify();"/>
274<p>Verification status: <span id="verify-result">pending</span></p>
275
276</body>
277</html>