From c4c47f777724937746c99c064e65f52723443e59 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 20 Aug 2020 22:47:33 +0200 Subject: first cut on implementing additional encryption with the SJCL library. aes only and no backward compatibility. --- view/js/crypto.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) (limited to 'view/js/crypto.js') diff --git a/view/js/crypto.js b/view/js/crypto.js index c3a37d177..058b769c5 100644 --- a/view/js/crypto.js +++ b/view/js/crypto.js @@ -131,6 +131,63 @@ function red_encrypt(alg, elem,text) { // } } +function hz_encrypt(alg, elem) { + var enc_text = ''; + var newdiv = ''; + + if(typeof tinyMCE !== "undefined") + tinyMCE.triggerSave(false,true); + + var text = $(elem).val(); + + // key and hint need to be localised + + var passphrase = prompt(aStr['passphrase']); + // let the user cancel this dialogue + if (passphrase == null) + return false; + var enc_key = bin2hex(passphrase); + + // If you don't provide a key you get rot13, which doesn't need a key + // but consequently isn't secure. + + if(! enc_key) + alg = 'rot13'; + + if((alg == 'rot13') || (alg == 'triple-rot13')) + newdiv = "[crypt alg='rot13']" + window.btoa(str_rot13(text)) + '[/crypt]'; + + if(alg == 'AES-256') { + + // This is the prompt we're going to use when the receiver tries to open it. + // Maybe "Grandma's maiden name" or "our secret place" or something. + + var enc_hint = bin2hex(prompt(aStr['passhint'])); + + enc_text = sjcl.encrypt(enc_key, text, { ks: 256 }); + + encrypted = enc_text.toString(); + + newdiv = "[crypt alg='AES-256' hint='" + enc_hint + "']" + window.btoa(encrypted) + '[/crypt]'; + } + + enc_key = ''; + + // This might be a comment box on a page with a tinymce editor + // so check if there is a tinymce editor but also check the display + // property of our source element - because a tinymce instance + // will have display "none". If a normal textarea such as in a comment + // box has display "none" you wouldn't be able to type in it. + + if($(elem).css('display') == 'none' && typeof tinyMCE !== "undefined") { + tinyMCE.activeEditor.setContent(newdiv); + } + else { + $(elem).val(newdiv); + } + +} + function red_decrypt(alg,hint,text,elem) { var dec_text = ''; @@ -180,7 +237,42 @@ function red_decrypt(alg,hint,text,elem) { } } - +function hz_decrypt(alg, hint, text, elem) { + + var dec_text = ''; + + text = window.atob(text); + + if(alg == 'rot13' || alg == 'triple-rot13') + dec_text = str_rot13(text); + else { + var enc_key = bin2hex(prompt((hint.length) ? hex2bin(hint) : aStr['passphrase'])); + } + + if(alg == 'AES-256') { + dec_text = sjcl.decrypt(enc_key, text); + } + + enc_key = ''; + + // Not sure whether to drop this back in the conversation display. + // It probably needs a lightbox or popup window because any conversation + // updates could + // wipe out the text and make you re-enter the key if it was in the + // conversation. For now we do that so you can read it. + + var dec_result = dec_text.toString(); + delete dec_text; + + // incorrect decryptions *usually* but don't always have zero length + // If the person typo'd let them try again without reloading the page + // otherwise they'll have no "padlock" to click to try again. + + if(dec_result.length) { + $(elem).html(b2h(dec_result)); + dec_result = ''; + } +} -- cgit v1.2.3 From 49df57df45f82e2e0f1b10f2508f61b78d6d3ac0 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 21 Aug 2020 10:55:55 +0200 Subject: use the default setting and also add the mode to the cipher. aes-128 is to be preferred over aes-256 according to bruce schneier https://www.schneier.com/blog/archives/2009/07/another_new_aes.html#c386957 --- view/js/crypto.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'view/js/crypto.js') diff --git a/view/js/crypto.js b/view/js/crypto.js index 058b769c5..98af6e09e 100644 --- a/view/js/crypto.js +++ b/view/js/crypto.js @@ -157,18 +157,18 @@ function hz_encrypt(alg, elem) { if((alg == 'rot13') || (alg == 'triple-rot13')) newdiv = "[crypt alg='rot13']" + window.btoa(str_rot13(text)) + '[/crypt]'; - if(alg == 'AES-256') { + if(alg == 'AES-128-CCM') { // This is the prompt we're going to use when the receiver tries to open it. // Maybe "Grandma's maiden name" or "our secret place" or something. var enc_hint = bin2hex(prompt(aStr['passhint'])); - enc_text = sjcl.encrypt(enc_key, text, { ks: 256 }); + enc_text = sjcl.encrypt(enc_key, text); encrypted = enc_text.toString(); - newdiv = "[crypt alg='AES-256' hint='" + enc_hint + "']" + window.btoa(encrypted) + '[/crypt]'; + newdiv = "[crypt alg='AES-128-CCM' hint='" + enc_hint + "']" + window.btoa(encrypted) + '[/crypt]'; } enc_key = ''; @@ -249,7 +249,7 @@ function hz_decrypt(alg, hint, text, elem) { var enc_key = bin2hex(prompt((hint.length) ? hex2bin(hint) : aStr['passphrase'])); } - if(alg == 'AES-256') { + if(alg == 'AES-128-CCM') { dec_text = sjcl.decrypt(enc_key, text); } -- cgit v1.2.3 From 4e0fc81e5dfaad3c3ed47a02df4589f5b25a88be Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 22 Aug 2020 22:14:29 +0200 Subject: move cryptojs to addon --- view/js/crypto.js | 278 +----------------------------------------------------- 1 file changed, 5 insertions(+), 273 deletions(-) (limited to 'view/js/crypto.js') diff --git a/view/js/crypto.js b/view/js/crypto.js index 98af6e09e..14bc1e0a2 100644 --- a/view/js/crypto.js +++ b/view/js/crypto.js @@ -1,4 +1,3 @@ - function str_rot13 (str) { // http://kevin.vanzonneveld.net // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) @@ -16,121 +15,6 @@ function str_rot13 (str) { }); } - -// Arrays for pluggable encryptors/decryptors - -var red_encryptors = new Array(); -var red_decryptors = new Array(); - -// We probably just want the element where the text is and find it ourself. e.g. if -// there is highlighted text use it, otherwise use the entire text. -// So the third element may be useless. Fix also in view/tpl/jot.tpl before -// adding to all the editor templates and enabling the feature - -// Should probably do some input sanitising and dealing with bbcode, hiding key text, and displaying -// results in a lightbox and/or popup form are left as an exercise for the reader. - - -function red_encrypt(alg, elem,text) { - var enc_text = ''; - var newdiv = ''; - - if(typeof tinyMCE !== "undefined") - tinyMCE.triggerSave(false,true); - - var text = $(elem).val(); - - // key and hint need to be localised - - var passphrase = prompt(aStr['passphrase']); - // let the user cancel this dialogue - if (passphrase == null) - return false; - var enc_key = bin2hex(passphrase); - - // If you don't provide a key you get rot13, which doesn't need a key - // but consequently isn't secure. - - if(! enc_key) - alg = 'rot13'; - - if((alg == 'rot13') || (alg == 'triple-rot13')) - newdiv = "[crypt alg='rot13']" + str_rot13(text) + '[/crypt]'; - - if(alg == 'aes256') { - - // This is the prompt we're going to use when the receiver tries to open it. - // Maybe "Grandma's maiden name" or "our secret place" or something. - - var enc_hint = bin2hex(prompt(aStr['passhint'])); - - enc_text = CryptoJS.AES.encrypt(text,enc_key); - - encrypted = enc_text.toString(); - - newdiv = "[crypt alg='aes256' hint='" + enc_hint + "']" + encrypted + '[/crypt]'; - } - if(alg == 'rabbit') { - - // This is the prompt we're going to use when the receiver tries to open it. - // Maybe "Grandma's maiden name" or "our secret place" or something. - - var enc_hint = bin2hex(prompt(aStr['passhint'])); - - enc_text = CryptoJS.Rabbit.encrypt(text,enc_key); - encrypted = enc_text.toString(); - - newdiv = "[crypt alg='rabbit' hint='" + enc_hint + "']" + encrypted + '[/crypt]'; - } - if(alg == '3des') { - - // This is the prompt we're going to use when the receiver tries to open it. - // Maybe "Grandma's maiden name" or "our secret place" or something. - - var enc_hint = bin2hex(prompt(aStr['passhint'])); - - enc_text = CryptoJS.TripleDES.encrypt(text,enc_key); - encrypted = enc_text.toString(); - - newdiv = "[crypt alg='3des' hint='" + enc_hint + "']" + encrypted + '[/crypt]'; - } - if((red_encryptors.length) && (! newdiv.length)) { - for(var i = 0; i < red_encryptors.length; i ++) { - newdiv = red_encryptors[i](alg,text); - if(newdiv.length) - break; - } - } - - enc_key = ''; - -// alert(newdiv); - - // This might be a comment box on a page with a tinymce editor - // so check if there is a tinymce editor but also check the display - // property of our source element - because a tinymce instance - // will have display "none". If a normal textarea such as in a comment - // box has display "none" you wouldn't be able to type in it. - - if($(elem).css('display') == 'none' && typeof tinyMCE !== "undefined") { - tinyMCE.activeEditor.setContent(newdiv); - } - else { - $(elem).val(newdiv); - } - -// textarea = document.getElementById(elem); -// if (document.selection) { -// textarea.focus(); -// selected = document.selection.createRange(); -// selected.text = newdiv; -// } else if (textarea.selectionStart || textarea.selectionStart == "0") { -// var start = textarea.selectionStart; -// var end = textarea.selectionEnd; -// textarea.value = textarea.value.substring(0, start) + newdiv + textarea.value.substring(end, textarea.value.length); -// } -} - function hz_encrypt(alg, elem) { var enc_text = ''; var newdiv = ''; @@ -188,59 +72,17 @@ function hz_encrypt(alg, elem) { } -function red_decrypt(alg,hint,text,elem) { +function hz_decrypt(alg, hint, text, elem) { var dec_text = ''; - if(alg == 'rot13' || alg == 'triple-rot13') - dec_text = str_rot13(text); - else { - var enc_key = bin2hex(prompt((hint.length) ? hex2bin(hint) : aStr['passphrase'])); - } - - if(alg == 'aes256') { - dec_text = CryptoJS.AES.decrypt(text,enc_key); - } - if(alg == 'rabbit') { - dec_text = CryptoJS.Rabbit.decrypt(text,enc_key); - } - if(alg == '3des') { - dec_text = CryptoJS.TripleDES.decrypt(text,enc_key); - } + var supported = ['AES-128-CCM', 'rot13', 'triple-rot13']; - if((red_decryptors.length) && (! dec_text.length)) { - for(var i = 0; i < red_decryptors.length; i ++) { - dec_text = red_decryptors[i](alg,text,enc_key); - if(dec_text.length) - break; - } + if(supported.indexOf(alg) < 0) { + alert('Sorry, this encryption type is not supported anymore.\r\nConsider asking your admin to install the cryptojs addon for legacy crypto support.'); + return; } - enc_key = ''; - - // Not sure whether to drop this back in the conversation display. - // It probably needs a lightbox or popup window because any conversation - // updates could - // wipe out the text and make you re-enter the key if it was in the - // conversation. For now we do that so you can read it. - - var dec_result = dec_text.toString(CryptoJS.enc.Utf8); - delete dec_text; - - // incorrect decryptions *usually* but don't always have zero length - // If the person typo'd let them try again without reloading the page - // otherwise they'll have no "padlock" to click to try again. - - if(dec_result.length) { - $(elem).html(b2h(dec_result)); - dec_result = ''; - } -} - -function hz_decrypt(alg, hint, text, elem) { - - var dec_text = ''; - text = window.atob(text); if(alg == 'rot13' || alg == 'triple-rot13') @@ -274,113 +116,3 @@ function hz_decrypt(alg, hint, text, elem) { } } - - -function base64_encode (data) { - // http://kevin.vanzonneveld.net - // + original by: Tyler Akins (http://rumkin.com) - // + improved by: Bayron Guevara - // + improved by: Thunder.m - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + bugfixed by: Pellentesque Malesuada - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + improved by: Rafa? Kukawski (http://kukawski.pl) - // * example 1: base64_encode('Kevin van Zonneveld'); - // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' - // mozilla has this native - // - but breaks in 2.0.0.12! - //if (typeof this.window['btoa'] === 'function') { - // return btoa(data); - //} - var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, - ac = 0, - enc = "", - tmp_arr = []; - - if (!data) { - return data; - } - - do { // pack three octets into four hexets - o1 = data.charCodeAt(i++); - o2 = data.charCodeAt(i++); - o3 = data.charCodeAt(i++); - - bits = o1 << 16 | o2 << 8 | o3; - - h1 = bits >> 18 & 0x3f; - h2 = bits >> 12 & 0x3f; - h3 = bits >> 6 & 0x3f; - h4 = bits & 0x3f; - - // use hexets to index into b64, and append result to encoded string - tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); - } while (i < data.length); - - enc = tmp_arr.join(''); - - var r = data.length % 3; - - return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); - -} - - -function base64_decode (data) { - // http://kevin.vanzonneveld.net - // + original by: Tyler Akins (http://rumkin.com) - // + improved by: Thunder.m - // + input by: Aman Gupta - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + bugfixed by: Onno Marsman - // + bugfixed by: Pellentesque Malesuada - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Brett Zamir (http://brett-zamir.me) - // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); - // * returns 1: 'Kevin van Zonneveld' - // mozilla has this native - // - but breaks in 2.0.0.12! - //if (typeof this.window['atob'] === 'function') { - // return atob(data); - //} - var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, - ac = 0, - dec = "", - tmp_arr = []; - - if (!data) { - return data; - } - - data += ''; - - do { // unpack four hexets into three octets using index points in b64 - h1 = b64.indexOf(data.charAt(i++)); - h2 = b64.indexOf(data.charAt(i++)); - h3 = b64.indexOf(data.charAt(i++)); - h4 = b64.indexOf(data.charAt(i++)); - - bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; - - o1 = bits >> 16 & 0xff; - o2 = bits >> 8 & 0xff; - o3 = bits & 0xff; - - if (h3 == 64) { - tmp_arr[ac++] = String.fromCharCode(o1); - } else if (h4 == 64) { - tmp_arr[ac++] = String.fromCharCode(o1, o2); - } else { - tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); - } - } while (i < data.length); - - dec = tmp_arr.join(''); - - return dec; -} - - -- cgit v1.2.3