最近新项目上线,被客户扫描出【已解密的登录请求】,原因是我们在登录请求时没有对用户名或密码进行加密请求(悲催,以前的项目没有进行加密也没出啥问题),本着客户至上的原则,我们在下次投产时把这个功能给加上。
在网上关于JS和java互通加解密的算法有很多,比如DES、RSA、base64和AES等。权衡之下选择了AES加解密算法。
好了,废话不多说,开始我们的代码之旅吧。
登录界面JS实现
需要引入 aes.js依赖包
pageEncoding="UTF-8"%>
登录登录!
账号:
密码:
登录
重置
$(document).ready(function() {
document.getElementById('loginButton').onclick = function() {
var account = $('#account').val();
var password = $('#password').val();
if(account == '') {
alert("用户账号不能为空");
return;
}
if(password == ''){
alert("密码不能为空");
return;
}
//加密
account = encryptAES(account);
password = encryptAES(password);
$.ajax({
url: "${pageContext.request.contextPath}/rest/login",
data: {account:account,password:password},
type: "POST",
dataType:"json",
success: function(res) {
if(res.statu == '0') {
alert("登录成功!");
}else {
alert(res.msg);
}
}
})
}
})
//js aes加密
function encryptAES(str) {
var key = CryptoJS.enc.Latin1.parse('abcdef0123456789');
var iv = CryptoJS.enc.Latin1.parse('0123456789abcdef');
//加密
var encrypted = CryptoJS.AES.encrypt(str, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
console.log(encrypted.toString())
//encrypted = encrypted.toString().replace(/\+/g,"%2B");
return encrypted.toString();
}
//js aes解密
function decryptAES(str) {
}
java代码实现
登录类LoginController
package ban.aes.www.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import ban.aes.www.common.AESTool;
import ban.aes.www.common.Constant;
@RestController
@RequestMapping(value = "/rest")
public class LoginController {
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Map login(String account, String password) {
Map map = new HashMap();
// 解密
try {
account = AESTool.decryptAES(account).trim();
password = AESTool.decryptAES(password).trim();
// 判断解密后的账号和密码
// 真实的业务场景需要去数据库中查询,这里我为了简单定义成常量
if (Constant.ACCOUNT.equals(account) && Constant.PASSWORD.equals(password)) {
map.put("statu", "0");// 0代表成功
} else {
map.put("statu", "1");// 1代表失败
map.put("msg", "用户名或密码错误");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
}
常量类
package ban.aes.www.common;
public class Constant {
/**
* 账号
*/
public static final String ACCOUNT = "555116024";
/**
* 密码
*/
public static final String PASSWORD = "join@123";
}
AESTool工具类
package ban.aes.www.common;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
public class AESTool {
// static String data = "123456RWEQR";
static String key = "abcdef0123456789"; // 16位
static String iv = "0123456789abcdef"; // 16位
public static String encryptAES(String data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding"); // 参数分别代表 算法名称/加密模式/数据填充方式
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes();
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return new sun.misc.BASE64Encoder().encode(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decryptAES(String data) throws Exception {
try {
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(data);
Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
完整的代码我已经上传到git上了,大家可以关注公众号回复aes获取完整的代码,还可以获取更多的java干货只是,拿到各种java技术视屏和资料。