漏洞说明
关键信息明文传输也是一个十分常见的漏洞。在前后端进行交互时,尤其是登录操作,需要注意对密码等关键信息进行加密,因为信息在传输过程中,可能会有被截获的危险。下面就针对扫描工具,给出几种方案。
修复方案
-
第一种 base64
严格来说,base64其实算不上加密?毕竟base64只是一种常见的编码格式,但是对于安全性要求不太高的系统,也可以使用base64来避免漏洞扫描工具报出“关键信息明文传输”的漏洞。base64使用简单,直接贴代码如下:
//前端进行加密编码
var b = new Base64();
var password_encode = b.encode(trim(password.value));
document.getElementById("password").value=password_encode;
//后端进行解密编码
password = PasswordUtils.getFromBase64(password);
//解码具体方法
public static String getFromBase64(String str)
{
byte[] b = null;
String result = null;
if (str != null)
{
BASE64Decoder decoder = new BASE64Decoder();
try
{
b = decoder.decodeBuffer(str);
result = new String(b, "UTF-8");
}
catch (Exception e)
{
e.printStackTrace();
}
}
return result;
}
-
第二种 AES加密
AES加密原理可以参考 https://blog.csdn.net/gulang03/article/details/81175854 原文作者写的真的很详细,我这里就直接贴代码了,jsp中需要引入aes.js
和mode-ecb.js
:
//前端加密,秘钥长度需为16位,这里我使用当前系统时间+abc构成的16位字符串做秘钥,并将秘钥存入Session中
<%
String key = Long.toString(new Date().getTime()) + "abc";
session.removeAttribute("AESKey");
session.setAttribute("AESKey", key);
%>
var password = document.getElementById("password").value;
var aeskey = CryptoJS.enc.Utf8.parse("<%= key%>");
var srcs = CryptoJS.enc.Utf8.parse(password);
var encrypted = CryptoJS.AES.encrypt(srcs, aeskey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
document.getElementById("password").value = encrypted.toString();
//后端解密
password = PasswordUtils.decryptAES(request, password);
/**
* AES解密
* @param req 用户请求,用于获取session中的aeskey
* @param data 需要解密的数据
* @return 返回解密的数据
* @throws Exception
*/
public static String decryptAES(HttpServletRequest req, String data) throws Exception {
try {
HttpSession session = req.getSession();
String key = StringUtil.ob2string(session.getAttribute("AESKey"));
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(data);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, keyspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
另外补一个注意事项,对于AES三中数据填充方式: