First, sources of demand

When making H5 page push, my colleagues at the back end required me to put the parameters related to identity information in the URL through base64 encryption. When they heard such a requirement, they would say, isn’t it unsafe?

Let’s forget about security, let’s just talk about implementation, since there is such a need then I will meet you. As long as you understand this idea, you can derive inferential results. Even if you change the encryption mode to other encryption methods, change the plaintext mode to ciphertext mode, and obtain the parameters through the authentication interface, it can be realized.

Second, implementation ideas

First base a base64 decoding transcoding JS code, and then write a method to generate a watermark, and finally combined together can achieve this requirement.

Three, the code

1.base64.js

function Base64() { // private property var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // public method for encoding this.encode = function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = _utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); } return output; } // public method for decoding this.decode = function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9+/=]/g, ""); while (i < input.length) { enc1 = _keyStr.indexOf(input.charAt(i++)); enc2 = _keyStr.indexOf(input.charAt(i++)); enc3 = _keyStr.indexOf(input.charAt(i++)); enc4 = _keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 ! = 64) { output = output + String.fromCharCode(chr2); } if (enc4 ! = 64) { output = output + String.fromCharCode(chr3); } } output = _utf8_decode(output); return output; } // // private method for UTF-8 encoding var _utf8_encode = function (string) { string = string.replace(/\r\n/g,"\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; } // // // private method for UTF-8 decoding var _utf8_decode = function (utftext) { var string = ""; var i = 0; var c =0; var c2 = 0; var c3; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } export { Base64 }Copy the code

2. Generating watermarking method

Watermark(dom, TXT) {// Dom binding dom node if (! Dom) return false let length = txt.length * 20 Let canvas = document.createElement('canvas') Canvas.width = length canvas.height = length / 2 canvas.style.display = 'none' document.body.appendChild(canvas) let context = canvas.getContext('2d') context.font = '12px "PingFangSC", "Microsoft YaHei", "Helvetica Neue", Helvetica,Arial, Sans-serif 'context.fillstyle = 'rgba(0,0,0,0.5)' context.rotate(-10 * math.pi / 180) // the rotation Angle of text inside the canvas Context. FillText (TXT, length / 5, length / 3) // for(let I =0; i<dom.length; i++){ dom[i].style.backgroundImage = `url(${canvas.toDataURL('image/png')})` console.log(dom[i].style.backgroundImage) } },Copy the code

3. Method of obtaining parameters on the URL

Since I don’t want to use routing, I wrote a re to match the parameters on the URL

getQueryVariable(variable) { let query = window.location.search.substring(1); let vars = query.split("&"); for (let i=0; i<vars.length; i++) { let pair = vars[i].split("="); if(pair[0] == variable){return pair[1]; } } return(false); },Copy the code

4. Note: There are problems getting the parameters on the URL parameters

If the URL parameter contains Chinese characters, parsing errors will occur

The reason is that base64 encrypts some text with a + sign, and the + sign is automatically replaced by the browser at the URL with %20.

Solution: Convert %20 to a + sign using replace

import {Base64} from './base64.js';
name = base64.decode(decodeURIComponent(this.getQueryVariable('name').replace(/%20/g,'+')));
Copy the code

Four,

No matter in what way encryption decryption as long as the back end encryption decryption algorithm is consistent, and then pay attention to the details that will affect the results, can be achieved in accordance with the previous ideas.