转自原文:https://blog.csdn.net/weixin_42127766/article/details/82802189
RSA加密web前端用户名密码加密传输至后台并解密
第一步:编写加解密公共方法类RSAUtils
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
public class RSAUtils {
private static final KeyPair keyPair = initKey();
private static KeyPair initKey() {
try {
Provider provider =new BouncyCastleProvider();
Security.addProvider(provider);
SecureRandom random = new SecureRandom();
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider);
generator.initialize(1024,random);
return generator.generateKeyPair();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public static String generateBase64PublicKey() {
PublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
return new String(Base64.encodeBase64(publicKey.getEncoded()));
}
public static String decryptBase64(String string) {
return new String(decrypt(Base64.decodeBase64(string.getBytes())));
}
private static byte[] decrypt(byte[] byteArray) {
try {
Provider provider = new BouncyCastleProvider();
Security.addProvider(provider);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
PrivateKey privateKey = keyPair.getPrivate();
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plainText = cipher.doFinal(byteArray);
return plainText;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
第二步:前端在向后台发起登录请求之前,先请求后台获取公钥的方法
var publicKey = null;
$.ajax({
url: "xxx",
type: "post",
dataType: "text",
success: function(data) {
var encrypt = new JSEncrypt();
if(data){
publicKey = data;
};
if(publicKey==null){
$("#msg").html("获取publicKey失败,请联系管理员!");
$("#login-btn").removeAttr("disabled");
return;
};
}
});
后台生成公钥方法
@RequestMapping(value = "/xxxx", method = RequestMethod.POST)
public String getKey(HttpServletRequest request){
String publicKey = RSAUtils.generateBase64PublicKey();
return publicKey;
}
第三步:前端引入jsencrypt.min.js文件,github上下载jsencrypt,里面有这个文件。
第四步:js中通过公钥对用户名和密码加密,用加密后的用户名密码请求后台.
// 先获取公钥,然后提交用户名和密码给后台
$.ajax({
url: pUrl + "/getRandomKey",
type: "POST",
dataType: "text",
async: false,
success: function (publicKey) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
en_username = encrypt.encrypt(_$("username").value);
en_password = encrypt.encrypt(_$("mpassword").value);
// 提交用户名和密码给后台
$.ajax({
url: pUrl + "/j_spring_security_check",
data: {
"username":en_username,
"password":en_password,
"validateCode":_$("validateCode").value,
},
type: "POST",
dataType: "json",
success: function (msg) {
if (msg.loginSuccess) {
window.location.href = pUrl+"/ossapp/index.html";
} else {
showErrorMsg(msg.loginErrorMes);
_$("validateCode").value = "";
reloadCode();
}
}
});
}
});
请求成功之后的代码处理方式可以不用看,按照自己的需求进行处理就可以。这里重点强调一下用户名密码传输时千万不要字符串拼接方式传输,这样后台接收到密文解析的时候会将密文中的+号替换为空格,这样就会导致密文解析出错。
第五步:接下来就是后台接收前端传输过来的密文进行解密
String en_username = request.getParameter("username");
String en_pwd = obtainPassword(request);
username=SecurityUtils.decryptBase64(en_username.trim());
password=SecurityUtils.decryptBase64(en_pwd.trim());
到此已经完成了整个加密解密的流程,感谢原博主分享.
---------------------
作者:lyjunpm
来源:CSDN
原文:https://blog.csdn.net/weixin_42127766/article/details/82802189
版权声明:本文为博主原创文章,转载请附上博文链接!