問題背景:
前幾天項目做滲透測試的時候出現了兩個高危漏洞
經過排查發現是因為前端在登錄的時候沒有對密碼等用戶信息做加密處理
解決方案:
做一下最簡單的處理,前端采用JS自帶的 atob加密,后端采用工具解密
前端JS代碼:
//加密字符串,可以先將中文加密,然后再用btoa加密 encryption(str) { var encStr = encodeURIComponent(str); encStr = btoa(encStr); return encStr; }, //解密,可以先將ascii解密,然后再將非ascii解密 decrypt(str) { var decStr = atob(str); decStr = decodeURIComponent(decStr); return decStr; },
后端Java代碼:
package com.fudian.project.system.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; /** * Window.atob 加解密 * @author ZYGisComputer */ public class BtoaEncode { public static void main(String[] args) { String admin = BtoaEncode.encryption("admin"); System.out.println(admin); System.out.println(BtoaEncode.decrypt(admin)); } private static String base64hash = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; public static boolean isMatcher(String inStr, String reg) { Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(inStr); if (matcher.matches()) { return true; } return false; } /** * btoa method * @param inStr * @return */ public static String btoa(String inStr) { if (inStr == null || isMatcher(inStr, "([^\\u0000-\\u00ff])")) { return null; } StringBuilder result = new StringBuilder(); int i = 0; int mod = 0; int ascii; int prev = 0; while (i < inStr.length()) { ascii = inStr.charAt(i); mod = i % 3; switch (mod) { case 0: result.append(String.valueOf(base64hash.charAt(ascii >> 2))); break; case 1: result.append(String.valueOf(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)))); break; case 2: result.append(String.valueOf(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)))); result.append(String.valueOf(base64hash.charAt(ascii & 0x3f))); break; } prev = ascii; i++; } if (mod == 0) { result.append(String.valueOf(base64hash.charAt((prev & 3) << 4))); result.append("=="); } else if (mod == 1) { result.append(String.valueOf(base64hash.charAt((prev & 0x0f) << 2))); result.append("="); } return result.toString(); } /** * atob method 逆轉encode的思路即可 * @param inStr * @return */ public static String atob(String inStr) { if (inStr == null) return null; inStr = inStr.replaceAll("\\s|=", ""); StringBuilder result = new StringBuilder(); int cur; int prev = -1; int mod; int i = 0; while (i < inStr.length()) { cur = base64hash.indexOf(inStr.charAt(i)); mod = i % 4; switch (mod) { case 0: break; case 1: result.append(String.valueOf((char) (prev << 2 | cur >> 4))); break; case 2: result.append(String.valueOf((char) ((prev & 0x0f) << 4 | cur >> 2))); break; case 3: result.append(String.valueOf((char) ((prev & 3) << 6 | cur))); break; } prev = cur; i++; } return result.toString(); } /** * 加密字符串 * @return */ public static String encryption(String str) { String encode; try { encode = URLEncoder.encode(str,"utf-8"); //URLEncoder.encode 會將空格解釋為+號 encode=encode.replaceAll("\\+", "%20"); String btoa = BtoaEncode.btoa(encode); return btoa; } catch (UnsupportedEncodingException e) { System.out.println("btoa加密函數出現錯誤。"); } return str; } /** * 解密字符串 * @return */ public static String decrypt(String str) { String atob = BtoaEncode.atob(str); try { String decode = URLDecoder.decode(atob, "utf-8"); return decode; } catch (UnsupportedEncodingException e) { System.out.println("atob加密函數出現錯誤。"); } return str; } }
測試:
前端測試:
通過輸入密碼為admin加密后得到 YW... 解密后得到admin
后端測試:
和前端一致,這樣才能做到加密解密的效果
建議:
整體來說就是一次最簡單的加密解密,當然這個相對不是特別安全,可以在這個基礎之上,對等於號做一些處理,再通過一些其他的算法來多次加密也可以,最好是一些帶隨機鹽的
作者:彼岸舞
時間:2020\12\23
內容關於:工作中用到的小技術
本文來源於網絡,只做技術分享,一概不負任何責任