1 2var cryptico = (function() { 3 4 var my = {}; 5 6 aes.Init(); 7 8 var base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 9 10 my.b256to64 = function(t) { 11 var a, c, n; 12 var r = '', l = 0, s = 0; 13 var tl = t.length; 14 for (n = 0; n < tl; n++) 15 { 16 c = t.charCodeAt(n); 17 if (s == 0) 18 { 19 r += base64Chars.charAt((c >> 2) & 63); 20 a = (c & 3) << 4; 21 } 22 else if (s == 1) 23 { 24 r += base64Chars.charAt((a | (c >> 4) & 15)); 25 a = (c & 15) << 2; 26 } 27 else if (s == 2) 28 { 29 r += base64Chars.charAt(a | ((c >> 6) & 3)); 30 l += 1; 31 r += base64Chars.charAt(c & 63); 32 } 33 l += 1; 34 s += 1; 35 if (s == 3) s = 0; 36 } 37 if (s > 0) 38 { 39 r += base64Chars.charAt(a); 40 l += 1; 41 r += '='; 42 l += 1; 43 } 44 if (s == 1) 45 { 46 r += '='; 47 } 48 return r; 49 } 50 51 my.b64to256 = function(t) 52 { 53 var c, n; 54 var r = '', s = 0, a = 0; 55 var tl = t.length; 56 for (n = 0; n < tl; n++) 57 { 58 c = base64Chars.indexOf(t.charAt(n)); 59 if (c >= 0) 60 { 61 if (s) r += String.fromCharCode(a | (c >> (6 - s)) & 255); 62 s = (s + 2) & 7; 63 a = (c << s) & 255; 64 } 65 } 66 return r; 67 } 68 69 my.b16to64 = function(h) { 70 var i; 71 var c; 72 var ret = ""; 73 if(h.length % 2 == 1) 74 { 75 h = "0" + h; 76 } 77 for (i = 0; i + 3 <= h.length; i += 3) 78 { 79 c = parseInt(h.substring(i, i + 3), 16); 80 ret += base64Chars.charAt(c >> 6) + base64Chars.charAt(c & 63); 81 } 82 if (i + 1 == h.length) 83 { 84 c = parseInt(h.substring(i, i + 1), 16); 85 ret += base64Chars.charAt(c << 2); 86 } 87 else if (i + 2 == h.length) 88 { 89 c = parseInt(h.substring(i, i + 2), 16); 90 ret += base64Chars.charAt(c >> 2) + base64Chars.charAt((c & 3) << 4); 91 } 92 while ((ret.length & 3) > 0) ret += "="; 93 return ret; 94 } 95 96 my.b64to16 = function(s) { 97 var ret = ""; 98 var i; 99 var k = 0; 100 var slop; 101 for (i = 0; i < s.length; ++i) 102 { 103 if (s.charAt(i) == "=") break; 104 v = base64Chars.indexOf(s.charAt(i)); 105 if (v < 0) continue; 106 if (k == 0) 107 { 108 ret += int2char(v >> 2); 109 slop = v & 3; 110 k = 1; 111 } 112 else if (k == 1) 113 { 114 ret += int2char((slop << 2) | (v >> 4)); 115 slop = v & 0xf; 116 k = 2; 117 } 118 else if (k == 2) 119 { 120 ret += int2char(slop); 121 ret += int2char(v >> 2); 122 slop = v & 3; 123 k = 3; 124 } 125 else 126 { 127 ret += int2char((slop << 2) | (v >> 4)); 128 ret += int2char(v & 0xf); 129 k = 0; 130 } 131 } 132 if (k == 1) ret += int2char(slop << 2); 133 return ret; 134 } 135 136 // Converts a string to a byte array. 137 my.string2bytes = function(string) 138 { 139 var bytes = new Array(); 140 for(var i = 0; i < string.length; i++) 141 { 142 bytes.push(string.charCodeAt(i)); 143 } 144 return bytes; 145 } 146 147 // Converts a byte array to a string. 148 my.bytes2string = function(bytes) 149 { 150 var string = ""; 151 for(var i = 0; i < bytes.length; i++) 152 { 153 string += String.fromCharCode(bytes[i]); 154 } 155 return string; 156 } 157 158 // Returns a XOR b, where a and b are 16-byte byte arrays. 159 my.blockXOR = function(a, b) 160 { 161 var xor = new Array(16); 162 for(var i = 0; i < 16; i++) 163 { 164 xor[i] = a[i] ^ b[i]; 165 } 166 return xor; 167 } 168 169 // Returns a 16-byte initialization vector. 170 my.blockIV = function() 171 { 172 var r = new SecureRandom(); 173 var IV = new Array(16); 174 r.nextBytes(IV); 175 return IV; 176 } 177 178 // Returns a copy of bytes with zeros appended to the end 179 // so that the (length of bytes) % 16 == 0. 180 my.pad16 = function(bytes) 181 { 182 var newBytes = bytes.slice(0); 183 var padding = (16 - (bytes.length % 16)) % 16; 184 for(i = bytes.length; i < bytes.length + padding; i++) 185 { 186 newBytes.push(0); 187 } 188 return newBytes; 189 } 190 191 // Removes trailing zeros from a byte array. 192 my.depad = function(bytes) 193 { 194 var newBytes = bytes.slice(0); 195 while(newBytes[newBytes.length - 1] == 0) 196 { 197 newBytes = newBytes.slice(0, newBytes.length - 1); 198 } 199 return newBytes; 200 } 201 202 // AES CBC Encryption. 203 my.encryptAESCBC = function(plaintext, key) 204 { 205 var exkey = key.slice(0); 206 aes.ExpandKey(exkey); 207 var blocks = my.string2bytes(plaintext); 208 blocks = my.pad16(blocks); 209 var encryptedBlocks = my.blockIV(); 210 for(var i = 0; i < blocks.length/16; i++) 211 { 212 var tempBlock = blocks.slice(i * 16, i * 16 + 16); 213 var prevBlock = encryptedBlocks.slice((i) * 16, (i) * 16 + 16); 214 tempBlock = my.blockXOR(prevBlock, tempBlock); 215 aes.Encrypt(tempBlock, exkey); 216 encryptedBlocks = encryptedBlocks.concat(tempBlock); 217 } 218 var ciphertext = my.bytes2string(encryptedBlocks); 219 return my.b256to64(ciphertext) 220 } 221 222 // AES CBC Decryption. 223 my.decryptAESCBC = function(encryptedText, key) 224 { 225 var exkey = key.slice(0); 226 aes.ExpandKey(exkey); 227 var encryptedText = my.b64to256(encryptedText); 228 var encryptedBlocks = my.string2bytes(encryptedText); 229 var decryptedBlocks = new Array(); 230 for(var i = 1; i < encryptedBlocks.length/16; i++) 231 { 232 var tempBlock = encryptedBlocks.slice(i * 16, i * 16 + 16); 233 var prevBlock = encryptedBlocks.slice((i-1) * 16, (i-1) * 16 + 16); 234 aes.Decrypt(tempBlock, exkey); 235 tempBlock = my.blockXOR(prevBlock, tempBlock); 236 decryptedBlocks = decryptedBlocks.concat(tempBlock); 237 } 238 decryptedBlocks = my.depad(decryptedBlocks); 239 return my.bytes2string(decryptedBlocks); 240 } 241 242 // Wraps a string to 60 characters. 243 my.wrap60 = function(string) 244 { 245 var outstr = ""; 246 for(var i = 0; i < string.length; i++) { 247 if(i % 60 == 0 && i != 0) outstr += "\n"; 248 outstr += string[i]; } 249 return outstr; 250 } 251 252 // Generate a random key for the AES-encrypted message. 253 my.generateAESKey = function() 254 { 255 var key = new Array(32); 256 var r = new SecureRandom(); 257 r.nextBytes(key); 258 return key; 259 } 260 261 // Generates an RSA key from a passphrase. 262 my.generateRSAKey = function(passphrase, bitlength) 263 { 264 Math.seedrandom(sha256.hex(passphrase)); 265 var rsa = new RSAKey(); 266 rsa.generate(bitlength, "03"); 267 return rsa; 268 } 269 270 // Returns the ascii-armored version of the public key.
271 my.publicKeyString = function(rsakey) 272 { 273 pubkey = my.b16to64(rsakey.n.toString(16)); 274 return pubkey; 275 } 276 277 // Returns an MD5 sum of a publicKeyString for easier identification. 278 my.publicKeyID = function(publicKeyString) 279 { 280 return MD5(publicKeyString); 281 } 282 283 my.publicKeyFromString = function(string) 284 { 285 var N = my.b64to16(string.split("|")[0]); 286 var E = "03"; 287 var rsa = new RSAKey(); 288 rsa.setPublic(N, E); 289 return rsa 290 } 291 292 my.encrypt = function(plaintext, publickeystring, signingkey) 293 { 294 var cipherblock = ""; 295 var aeskey = my.generateAESKey(); 296 try 297 { 298 var publickey = my.publicKeyFromString(publickeystring); 299 cipherblock += my.b16to64(publickey.encrypt(my.bytes2string(aeskey))) + "?"; 300 } 301 catch(err) 302 { 303 return {status: "Invalid public key"}; 304 } 305 if(signingkey) 306 { 307 signString = cryptico.b16to64(signingkey.signString(plaintext, "sha256")); 308 plaintext += "::52cee64bb3a38f6403386519a39ac91c::"; 309 plaintext += cryptico.publicKeyString(signingkey); 310 plaintext += "::52cee64bb3a38f6403386519a39ac91c::"; 311 plaintext += signString; 312 } 313 cipherblock += my.encryptAESCBC(plaintext, aeskey); 314 return {status: "success", cipher: cipherblock}; 315 } 316 317 my.decrypt = function(ciphertext, key) 318 { 319 var cipherblock = ciphertext.split("?"); 320 var aeskey = key.decrypt(my.b64to16(cipherblock[0])); 321 if(aeskey == null) 322 { 323 return {status: "failure"}; 324 } 325 aeskey = my.string2bytes(aeskey); 326 var plaintext = my.decryptAESCBC(cipherblock[1], aeskey).split("::52cee64bb3a38f6403386519a39ac91c::"); 327 if(plaintext.length == 3) 328 { 329 var publickey = my.publicKeyFromString(plaintext[1]); 330 var signature = my.b64to16(plaintext[2]); 331 if(publickey.verifyString(plaintext[0], signature)) 332 { 333 return {status: "success", 334 plaintext: plaintext[0], 335 signature: "verified", 336 publicKeyString: my.publicKeyString(publickey)}; 337 } 338 else 339 { 340 return {status: "success", 341 plaintext: plaintext[0], 342 signature: "forged", 343 publicKeyString: my.publicKeyString(publickey)}; 344 } 345 } 346 else 347 { 348 return {status: "success", plaintext: plaintext[0], signature: "unsigned"}; 349 } 350 } 351 352 return my; 353 354}()); 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.