Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/cryptochat/trunk/tools/manual_create.php
Revision: 2
Committed: Thu May 2 09:05:04 2019 UTC (3 years, 2 months ago) by daniel-marschall
File size: 8765 byte(s)
Log Message:
Initial release to SVN

File Contents

# Content
1 <?php
2
3 // ViaThinkSoft CryptoChat
4 // (C) 2014 by Daniel Marschall, ViaThinkSoft
5 // Licensed under the terms of GPLv3
6
7 // -----------------------------------------------------------------------------------------------
8
9 require __DIR__ . '/../config/config.inc.php';
10 define('PRODUCT_NAME', 'CryptoChat');
11 define('MCC_VER', trim(file_get_contents(__DIR__ . '/../VERSION')));
12
13 header('Content-type: text/html; charset=utf-8');
14
15 ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
16 "http://www.w3.org/TR/html4/loose.dtd">
17
18 <html>
19
20 <head>
21 <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=utf-8">
22 <title><?php echo PRODUCT_NAME; ?> - Manually encrypt chat lines</title>
23
24 <script type="text/javascript" src="../<?php echo DEP_DIR_CRYPTOJS; ?>/rollups/sha256.js"></script>
25 <script type="text/javascript" src="../<?php echo DEP_DIR_CRYPTOJS; ?>/rollups/sha1.js"></script>
26 <script type="text/javascript" src="../<?php echo DEP_DIR_CRYPTOJS; ?>/rollups/aes.js"></script>
27 <script type="text/javascript" src="../<?php echo DEP_DIR_CRYPTOJS; ?>/rollups/md5.js"></script>
28
29 <script type="text/javascript">
30
31 var roomSalt = null;
32
33 // http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript/1349426#1349426
34 function randomString(len) {
35 var text = "";
36 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
37
38 for( var i=0; i < len; i++ ) {
39 text += possible.charAt(Math.floor(Math.random() * possible.length));
40 }
41
42 return text;
43 }
44
45 // --------------------------------------------
46
47 // --- MD5
48
49 var selftest_md5_finished = false;
50 function selftest_md5() {
51 if (selftest_md5_finished) return;
52 selftest_md5_finished = true;
53
54 var errors = "";
55 cmp_a = CryptoJS.enc.Base64.stringify(CryptoJS.MD5("Message"));
56 cmp_b = "TCqP5+ryRyHMep8BdRFb1A==";
57 if (cmp_a !== cmp_b) {
58 errors += "MD5 self test failed!\n";
59 console.error("MD5 self test failed: '" + cmp_a + "' vs. '" + cmp_b + "'");
60 }
61
62 if (errors) {
63 alert(errors+"\nYour browser seems to be buggy. Decryption of particular messages might fail.");
64 } else {
65 console.info("AES self test passed");
66 }
67 }
68
69 function md5(message) {
70 selftest_md5();
71 var hash = CryptoJS.MD5(message);
72 hash = CryptoJS.enc.Base64.stringify(hash);
73 return hash;
74 }
75
76 // --- SHA1
77
78 var selftest_sha1_finished = false;
79 function selftest_sha1() {
80 if (selftest_sha1_finished) return;
81 selftest_sha1_finished = true;
82
83 var errors = "";
84 cmp_a = CryptoJS.enc.Base64.stringify(CryptoJS.SHA1("Message"));
85 cmp_b = "aPQUX+593navzrkQFlkkrRTPDQA=";
86 if (cmp_a !== cmp_b) {
87 errors += "SHA1 self test failed!\n";
88 console.error("SHA1 self test failed: '" + cmp_a + "' vs. '" + cmp_b + "'");
89 }
90
91 if (errors) {
92 alert(errors+"\nYour browser seems to be buggy. Decryption of particular messages might fail.");
93 } else {
94 console.info("SHA1 self test passed");
95 }
96 }
97
98 function sha1(message) {
99 selftest_sha1();
100 var hash = CryptoJS.SHA1(message);
101 hash = CryptoJS.enc.Base64.stringify(hash);
102 return hash;
103 }
104
105 function sha1_base16(message) {
106 selftest_sha1();
107 return CryptoJS.SHA1(message).toString();
108 }
109
110 // --- SHA256
111
112 var selftest_sha256_finished = false;
113 function selftest_sha256() {
114 if (selftest_sha256_finished) return;
115 selftest_sha256_finished = true;
116
117 var errors = "";
118 cmp_a = CryptoJS.enc.Base64.stringify(CryptoJS.SHA256("Message"));
119 cmp_b = "L3dmip37+NWEi57rSnFFypTG7ZI25Kdz9tyvpRMrL5E=";
120 if (cmp_a !== cmp_b) {
121 errors += "SHA256 self test failed!\n";
122 console.error("SHA256 self test failed: '" + cmp_a + "' vs. '" + cmp_b + "'");
123 }
124
125 if (errors) {
126 alert(errors+"\nYour browser seems to be buggy. Decryption of particular messages might fail.");
127 } else {
128 console.info("AES self test passed");
129 }
130 }
131
132 function sha256(message) {
133 selftest_sha256();
134 var hash = CryptoJS.SHA256(message);
135 hash = CryptoJS.enc.Base64.stringify(hash);
136 return hash;
137 }
138
139 // --- AES
140
141 var selftest_aes_finished = false;
142 function selftest_aes() {
143 if (selftest_aes_finished) return;
144 selftest_aes_finished = true;
145
146 var errors = "";
147 var cmp_a = CryptoJS.AES.decrypt("U2FsdGVkX19kJJkA0NL7WJRdXKrdqDcf6A2yDODaL2g=", "Secret Passphrase").toString(CryptoJS.enc.Utf8);
148 var cmp_b = "Message";
149 if ((cmp_a !== cmp_b) || (aes_dec(aes_enc("Message")) !== "Message")) {
150 errors += "AES self test failed!\n";
151 console.error("AES self test failed: '" + cmp_a + "' vs. '" + cmp_b + "'");
152 }
153
154 if (errors) {
155 alert(errors+"\nYour browser seems to be buggy. Decryption of particular messages might fail.");
156 } else {
157 console.info("AES self test passed");
158 }
159 }
160
161 function aes_enc(msg, ver) {
162 // ver is currently not used
163 selftest_aes();
164 var passwd = getPassword();
165 return CryptoJS.AES.encrypt(msg, roomSalt+passwd);
166 }
167
168 function aes_dec(msg, ver) {
169 // ver is currently not used
170 selftest_aes();
171 var passwd = getPassword();
172 try {
173 return CryptoJS.AES.decrypt(msg, roomSalt+passwd).toString(CryptoJS.enc.Utf8);
174 } catch (e) {
175 return null;
176 }
177 }
178
179 # ---
180
181 // Alternative hash digest for compatibility issues
182 // Some browsers like Jumanji have problems using SHA1 or SHA2, but work with MD5, e.g.
183 // Jumanji 1.1.2.4 (versionsangabe nicht sicher) ist inkompatibel mit CryptoJS 3.1.2
184 // UA = "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+ jumanji/0.0"
185 // CryptoJS.MD5("Message"):
186 // - Normal: 4c2a8fe7eaf24721cc7a9f0175115bd4
187 // - Jumanji: 4c2a8fe7eaf24721cc7a9f0175115bd4 (OK)
188 // CryptoJS.SHA1("Message"):
189 // - Normal: 68f4145fee7dde76afceb910165924ad14cf0d00
190 // - Jumanji: 5a5aa74ecae1d696900b034d5f1b71497c170ea0 (Error)
191 // CryptoJS.SHA256("Message"):
192 // - Normal: 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
193 // - Jumanji: 5a28f8b8778c15a166f7f17ebb89ce8e8381fbb5e39ddc2511239793119a649e (Error)
194 // CryptoJS.AES.encrypt("Message", "Secret Passphrase"):
195 // - Normal: U2FsdGVkX19zlzNcfljComkcU0A7XfZ+gzZbI+GyFm0=
196 // - Jumanji: U2FsdGVkX19kJJkA0NL7WJRdXKrdqDcf6A2yDODaL2g= (OK)
197 // This is a fast version (4x MD5) necessary for slow computers with ARM architecture
198 function specialMD5fast4(message) {
199 var a = md5("IuErOmVyPeL2ek6e16vkjTWjssgLmd" + message);
200 var b = md5("8wxdm3mVi8UQXdboJvCctYwm8ZxTyX" + message);
201 return md5(a+b) + md5(b+a);
202 }
203
204 function specialHash(val, entrySalt, version) {
205 var hash = null;
206 if (version == 1) {
207 hash = sha256(roomSalt+entrySalt+val);
208 } else if (version == 2) {
209 hash = specialMD5fast4(roomSalt+entrySalt+val);
210 } else {
211 console.error("Version " + version + " is unknown at specialHash()");
212 return null;
213 }
214 return entrySalt + "_" + hash + "_ver" + version;
215 }
216
217 // --------------------------------------------
218
219 function getPassword() {
220 return document.getElementById("key").value;
221 }
222
223 function cbLine(str, p1, p2, p3, offset, s) {
224 var ver = document.getElementById("ver").value;
225 var passwd = document.getElementById("key").value;
226 var entrySalt = randomString(20);
227 var hash = specialHash(passwd, entrySalt, ver);
228
229 return "(date: "+p1+")(user: "+p2+")(dec_"+hash+": "+aes_enc(p3,ver)+")<br>\n";
230 }
231
232 function convert() {
233 var ses_room = document.getElementById("room").value;
234 var xsalt = document.getElementById("xsalt").value;
235 roomSalt = sha1_base16(xsalt + ses_room);
236
237 var message = document.getElementById("in").value + "\n";
238 message = message.replace(/(.+?) - \[(.+?)\]: (.+?)\n/g, cbLine);
239 document.getElementById("out").value = message;
240 }
241
242 function initPage() {
243 document.getElementById("out").value = "";
244 }
245 </script>
246
247 </head>
248
249 <body onload="initPage();">
250
251 <h1>Manually encrypt chat lines</h1>
252
253 <table border="0" cellpadding="5" cellspacing="0">
254 <tr>
255 <td>Server's X_SALT: </td>
256 <td><input style="width:500px" id="xsalt" value="<?php if (!KEEP_X_SALT_SECRET) echo X_SALT; ?>"></td>
257 </tr><tr>
258 <td>Algorithm: </td>
259 <td><select id="ver">
260 <option value="1"<?php if (CFG_CIPHERSUITE == 1) echo ' selected'; ?>>[1] SHA256</option>
261 <option value="2"<?php if (CFG_CIPHERSUITE == 2) echo ' selected'; ?>>[2] specialMD5fast4</option>
262 </select></td>
263 </tr><tr>
264 <td>Key: </td>
265 <td><input style="width:500px" id="key"></td>
266 </tr><tr>
267 <td>Chatroom name: </td>
268 <td><input style="width:500px" id="room"></td>
269 </tr><tr>
270 <td colspan="2">Input:<br>
271 <textarea id="in" cols="100" rows="6">2014-12-31 14:21:20 - [Daniel]: Hello world!
272 2014-12-31 14:21:22 - [Daniel]: Example!</textarea><br></td>
273 </tr><tr>
274 <td colspan="2"><input type="button" onclick="convert();" value="Convert"><br></td>
275 </tr><tr>
276 <td colspan="2">Output:<br>
277 <textarea id="out" cols="100" rows="6"></textarea></td>
278 </tr>
279 </table><br>
280 </body>
281
282 </html>
283