javaweb使⽤jsencrypt.js做RSA加密(⼀)
1 背景
在登录页⾯存在明⽂传输的漏洞,为了解决这个问题百度到了两种⽅案,第⼀种是使⽤https协议,许多⼈都推荐这种⽅案。第⼆种是对传
输的信息使⽤加密算法进⾏加密然后传输。
最后选择了第⼆种⽅案,原因是第⼀种的证书需要申请并且需要花钱,有免费证书有很多但⼤多有效期是⼀年。但⽹上评价https确实好,
个⼈感觉https还是⾸选,借⽤⽹友⼀句话“没有https的都是在裸奔”。
本⽂并不涉及https的相关内容,只是前端使⽤了jsencrypt.js,结合后端代码做了RSA加密。
2 代码
2.1准备jar和js
接下来的RSAUtils⼯具类需要导⼊commons-codec-1.10.jar,前端需要jsencrypt.js。以上传到SCDN下
载,不需要积分,编写本章时
在审核。百度云链接稍后发出。
2.2 ⼯具类
建⽴⼀个⼯具类RSAUtils,这个类借鉴了⽹友的代码,出处我忘记保存了。
使⽤这个类的initKey()⽅法⽣成密钥对,getPublicKey()⽅法可以得到公钥字符串,将其传输到前端中⽤于信息加密。
public class RSAUtils {
private static final String KEYALGORITHM = "RSA";
private static final String PUBLICKEY = "RSAPublicKey";
private static final String PRIVATEKEY = "RSAPrivateKey";
//rsa私钥或者可从配置⽂件读取。
/
/ public static final String DECRYPTPRIVATEKEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIMzJa4oZpQcPhRDTIaWnF4olSaeGt5o private RSAUtils(){super();}
public static byte[] decryptBASE64(String key) {
Base64 base64 = new Base64();
return base64.decode(key);
}
public static String encryptBASE64(byte[] bytes) {
Base64 base64 = new Base64();
deToString(bytes);
}
public static byte[] decryptByPrivateKey(byte[] data, String key){
try {
byte[] keyBytes = decryptBASE64(key);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = Instance(KEYALGORITHM);
Key privateKey = atePrivate(pkcs8KeySpec);
Cipher cipher = Algorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}catch (Exception e){
// ("RSAUtilsPrivateKeyDecryptError");
// ("RSAUtilsPrivateKeyDecryptError");
e.printStackTrace();
return new byte[0];
}
}
/**
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(String data, String key){
return decryptByPrivateKey(decryptBASE64(data), key);
}
/**
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String key){
try {
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = Instance(KEYALGORITHM);
Key publicKey = atePublic(x509KeySpec);
Cipher cipher = Algorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}catch (Exception e){
// ("RSAUtilsPublicKeyDecryptError");
e.printStackTrace();
return new byte[0];
}
}
/**
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(String data, String key) {
try {
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = Instance(KEYALGORITHM);
Key publicKey = atePublic(x509KeySpec);
js代码加密软件Cipher cipher = Algorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.Bytes());
}catch (Exception e){
// ("RSAUtilsPublicKeyEncryptError");
e.printStackTrace();
e.printStackTrace();
return new byte[0];
}
}
/**
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key){
try {
byte[] keyBytes = decryptBASE64(key);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = Instance(KEYALGORITHM);
Key privateKey = atePrivate(pkcs8KeySpec);
Cipher cipher = Algorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}catch (Exception e){
// ("RSAUtilsPrivateKeyEncryptError");
e.printStackTrace();
return new byte[0];
}
}
/**
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Key> keyMap){
if(keyMap != null){
Key key = (PRIVATEKEY);
return Encoded());
}else{
return "";
}
}
/**
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Key> keyMap){
if(keyMap != null){
Key key = (PUBLICKEY);
return Encoded());
}else {
return "";
}
}
/**
*
* @return
* @throws Exception
*/
*/
public static Map<String, Key> initKey(){
try {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEYALGORITHM);
keyPairGen.initialize(2048);
KeyPair keyPair = ateKeyPair();
Map<String, Key> keyMap = new HashMap(2);
keyMap.put(PUBLICKEY, Public());
keyMap.put(PRIVATEKEY, Private());
return keyMap;
} catch (NoSuchAlgorithmException e) {
// ("RSAUtilsInitKeyError");
e.printStackTrace();
return null;
}
}
}
2.3 前端请求公钥
2.3.1 后端java代码
这⾥采⽤了最简单的session存储密钥对。每次回话都⽣成新的密钥对,加强对信息的保护。将公钥暴露给前端。
PrintWriter out = Writer();
String generateKeypair = Parameter("generateKeypair");
HttpSession session = Session();
Map<String, Key> keyMap = (Map<String, Key>) Attribute("keyMap");
if (keyMap == null) {
keyMap = RSAUtils.initKey();
session.setAttribute("keyMap", keyMap);
}
String puk = PublicKey(keyMap);
out.println(puk);
2.3.2 前端js代码
先引⼊jsencrypt.js,在js中得到公钥,然后对数据进⾏加密。下⾯代码中contentEncrypted 变量就是加密之后的字符串。
$.ajax({
type : 'post',
url : 'url',
data : {
"generateKeypair" : true
},
success : function(result) {
//验证成功
PUBLIC_KEY = result
var encrypt = new JSEncrypt();
encrypt.setPublicKey(PUBLIC_KEY);
var contentEncrypted = pt(content)
}
});
2.4 后端代码解密。
前端将加密之后的信息传递到后端进⾏解密。附上后端代码,其中decryptContent 就是解密之后的字符串。
Map<String, Key> keyMap = (Map<String, Key>) Attribute("keyMap");
content = URLDecoder.decode(content,"UTF-8").replace(' ', '+');
String DECRYPTPRIVATEKEY = PrivateKey(keyMap);
byte[] decryptData = RSAUtils.decryptByPrivateKey(content, DECRYPTPRIVATEKEY);
String decryptContent = new String(decryptData);
这段代码有⼀点问题,中⽂解密出来会乱码,会不会和第⼆⾏有关,前端的pageEncoding="UTF-8",有没有⼤佬知道原因。
3 总结
私以为,上⾯的⽂字已经说得很清楚了,讲述了⼀点在java web中使⽤RSA进⾏数据加密的过程,其他的可以根据业务需求进⾏变化,本⾝还有很⼤的提升空间,所以本⽂的题⽬最后加了个“(⼀)”,在以后的学习中如果能再进⼀步,争取写个"(⼆)",欢迎各位指出不⾜。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论