-
Notifications
You must be signed in to change notification settings - Fork 0
/
rsa_calculator_demo.html
331 lines (290 loc) · 13.2 KB
/
rsa_calculator_demo.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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RSA Calculator by Syed Umar Anis</title>
<meta name="description" content="Demonstrate the working of Public Key Cryptography using RSA algorithm">
<meta name="author" content="Syed Umar Anis">
<meta property="og:type" content="website">
<meta property="og:title" content="RSA Calculator by Syed Umar Anis">
<meta property="og:description" content="Demonstrate the working of Public Key Cryptography using RSA algorithm">
<meta property="og:url" content="https://umaranis.com/rsa_calculator_demo.html">
<meta property="og:image" content="https://i2.wp.com/umaranis.com/wp-content/uploads/2018/08/Screenshot_2018-08-10-RSA-Calculator-by-Syed-Umar-Anis1.png?fit=953%2C1200&ssl=1">
<meta property="og:image:width" content="953">
<meta property="og:image:height" content="1200">
<meta property="og:locale" content="en_US">
<meta name="twitter:creator" content="@umaranis">
<link rel="icon" href="https://i0.wp.com/umaranis.com/wp-content/uploads/2020/12/cropped-android-chrome-384x384-1.png?fit=32%2C32&ssl=1" sizes="32x32">
<link rel="icon" href="https://i0.wp.com/umaranis.com/wp-content/uploads/2020/12/cropped-android-chrome-384x384-1.png?fit=192%2C192&ssl=1" sizes="192x192">
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/pure-min.css" integrity="sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" crossorigin="anonymous">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
header {
color: blue;
background-color: aliceblue;
padding:10px;
}
#clear {
clear: left
}
.help {
color: grey
}
td, th {
padding: 0px 10px 0px 10px;
text-align: left;
}
#enKeyListSpan, #deKeyListSpan {
color: red
}
.key {
padding: 10px;
margin: 1px;
border: 1px solid grey;
font-weight: bold
}
.key-label {
color:blue
}
.key-value {
color:red
}
article {
border: 1px solid grey;
margin: 10px 10px 30px 10px;
padding: 10px
}
.input-in-col {
width: 100px;
}
</style>
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<header>
<h1>
<div id="title">Public Key Cryptography using RSA algorithm</div>
</h1>
<div id="author">by: <a href="http://umaranis.com">Syed Umar Anis</a></div>
<div id="clear"></div>
</header>
<br/>
<article>
<div>Purpose of the page is to demonstrate how RSA algorithm works - generates keys, encrypts message and decrypts it.</div>
<div><p><a href="https://umaranis.com/2018/08/10/how-public-key-cryptography-works-rsa-algorithm/">See the related blog post</a> for more explanation.</p></div>
</article>
<article>
<h1>Step # 1: Generate Private and Public keys</h1>
<p>Enter two prime numbers below (P, Q), then press calculate:</p>
<div>
<div><p>P: <input type="text" id="p"></p></div>
<div><p>Q: <input type="text" id="q"></p></div>
<div><span class="help">Some prime numbers: 11, 13, 17, 19, 23, 29, 191, 193, 197, 199, etc. </span></div>
</div>
<p><input type="button" value="Calculate" onclick="calculate()"/></p>
<hr/>
<div style="overflow: auto;">
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
<th>Name</th>
<th>Formula</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>N</td>
<td><input type="text" id="n" class="input-in-col" readonly/></td>
<td>modulus</td>
<td>N: P * Q</td>
<td class="help">Product of 2 prime numbers</td>
</tr>
<tr>
<td>L</td>
<td><input type="text" id="l" class="input-in-col" readonly/></td>
<td>length</td>
<td>L: (p - 1) * (q - 1)</td>
<td class="help">Another way of calculating 'L' is to list of numbers from 1 to N, remove numbers which have common factor which
N and count the remaining numbers.</td>
</tr>
<tr>
<td>E</td>
<td><input type="text" id="e" class="input-in-col" onchange="encryptorChanged()"/></td>
<td>encryption key</td>
<td></td>
<td class="help">Find a number between 1 and L that is <a href="https://en.wikipedia.org/wiki/Coprime_integers" target="_blank">coprime</a> with L and N.<span id="enKeyListSpan"></span></td>
</tr>
<tr>
<td>D</td>
<td><input type="text" id="d" class="input-in-col" onchange="decryptorChanged()"/></td>
<td>decryption key</td>
<td>D * E mod L = 1</td>
<td class="help">Remainder of the product of D and E when divided by L should be 1 (D * E % L = 1)<span id="deKeyListSpan"></span></td>
</tr>
</tbody>
</table>
</div>
<br>
<section>
<div class="key">
<span class="key-label">Private Key (E, N): </span><span id="private-key" class="key-value"></span>
</div>
<div class="key">
<span class="key-label">Public Key (D, N): </span><span id="public-key" class="key-value"></span>
</div>
</section>
</article>
<article>
<h1>Step # 2: Encrypt a message</h1>
<p>Enter a message to encrypt: <input type="text" id="message"/></p>
<p><input type="button" value="Encrypt" onclick="encrypt()"/></p>
<hr/>
<p>Message converted to ASCII code: <span id="ascii"></span></p>
<p>Encrypted message: message^E % N <span class="help">(<a href="http://umaranis.com/2018/07/12/calculate-modular-exponentiation-powermod-in-javascript-ap-n/" >PowerMod</a> can be used to calculate this very fast. Formula is applied on ASCII code of each character.)</span></p>
<section>
<div class="key">
<span class="key-label">Encrypted Message: </span><span id="encrypted-msg" class="key-value"></span>
</div>
</section>
</article>
<article>
<h1>Step # 3: Decrypt a message</h1>
<p>Enter a encrypted message (cipher): <input type="text" id="encrypted-msg-textbox"/></p>
<p><input type="button" value="Decrypt" onclick="decrypt()"/></p>
<hr/>
<p>Message decrypted to ASCII code: <span id="ascii-decrypted"></span></p>
<p>Decrypted Message: encrypted_message^D % N <span class="help">(<a href="http://umaranis.com/2018/07/12/calculate-modular-exponentiation-powermod-in-javascript-ap-n/" >PowerMod</a> can be used to calculate this very fast. Formula is applied on ASCII code of each character.)</span></p>
<section>
<div class="key">
<span class="key-label">Decrypted Message: </span><span id="decrypted-msg" class="key-value"></span>
</div>
</section>
</article>
<script>
"use strict";
let e, d, n, l;
function validatePrime(prime, nameOfPrime) {
if(!isPrime(prime)) {
alert("'" + nameOfPrime + "' is not a prime number. Please enter a prime number.");
return false;
}
if(prime <= 7) {
alert("'" + nameOfPrime + "' should be greater than 7.");
return false;
}
return true;
}
function calculate() {
var p = document.getElementById("p").value;
var q = document.getElementById("q").value;
if (!(validatePrime(p, "p") && validatePrime(q, "q"))) return;
n = p * q;
document.getElementById("n").value = n;
l = (p - 1) * (q - 1);
document.getElementById("l").value = l;
var es = findEncryptionKeys(l, n);
document.getElementById("e").value = es[0];
document.getElementById("enKeyListSpan").innerHTML = " Possible encryption keys are: " + es;
encryptorChanged();
}
function encryptorChanged() {
e = document.getElementById("e").value;
var ds = findDecryptionKeys(e, l);
ds.splice(ds.indexOf(e), 1); //remove encryption key from list
d = ds[0];
document.getElementById("d").value = d;
document.getElementById("deKeyListSpan").innerHTML = " Possible decryption keys are: " + ds;
document.getElementById("private-key").innerHTML = "(" + e + "," + n + ")";
document.getElementById("public-key").innerHTML = "(" + d + "," + n + ")";
}
function decryptorChanged() {
d = document.getElementById("d").value;
document.getElementById("public-key").innerHTML = "(" + d + "," + n + ")";
}
function isPrime(num) {
for (let i = 2, s = Math.sqrt(num); i <= s; i++)
if (num % i === 0) return false;
return num !== 1;
}
function findEncryptionKeys(l, n) {
var arr = [];
for(var i = 2; i < l; i++) {
if(isCoPrime(i, l) && isCoPrime(i, n))
arr.push(i);
if(arr.length > 5) break;
}
return arr;
}
function isCoPrime(a, b) {
var aFac = findFactors(a);
var bFac = findFactors(b);
var result = aFac.every(x => bFac.indexOf(x) < 0);
return result;
}
var hashtable = new Object();
function findFactors(num) {
if(hashtable[num])
return hashtable[num];
var half = Math.floor(num / 2), // Ensures a whole number <= num.
result = [],
i, j;
//result.push(1); // 1 should be a part of every solution but for our purpose of COPRIME 1 should be excluded
// Determine out increment value for the loop and starting point.
num % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);
for (i; i <= half; i += j) {
num % i === 0 ? result.push(i) : false;
}
result.push(num); // Always include the original number.
hashtable[num] = result;
return result;
}
function findDecryptionKeys(e, l) {
var ds = [];
for(var x = l + 1;x < l + 100000; x++) {
if(x * e % l === 1) {
ds.push(x);
if(ds.length > 5) return ds;
}
}
return ds;
}
function encrypt() {
var m = document.getElementById("message").value;
var ascii = Array.from(Array(m.length).keys()).map(i => m.charCodeAt(i));
document.getElementById("ascii").innerHTML = ascii;
var encrypted = ascii.map(i => powerMod(i, e, n));
document.getElementById("encrypted-msg").innerHTML = encrypted;
document.getElementById("encrypted-msg-textbox").value = encrypted;
}
function decrypt() {
var cipher = stringToNumberArray(document.getElementById("encrypted-msg-textbox").value);
var ascii = cipher.map(i => powerMod(i, d, n));
document.getElementById("ascii-decrypted").innerHTML = ascii;
var message = "";
ascii.map(x => message += String.fromCharCode(x));
document.getElementById("decrypted-msg").innerHTML = message;
}
function stringToNumberArray(str) {
return str.split(",").map(i => parseInt(i));
}
// calculates base^exponent % modulus
function powerMod(base, exponent, modulus) {
if (modulus === 1) return 0;
var result = 1;
base = base % modulus;
while (exponent > 0) {
if (exponent % 2 === 1) //odd number
result = (result * base) % modulus;
exponent = exponent >> 1; //divide by 2
base = (base * base) % modulus;
}
return result;
}
</script>
</body>
</html>