加密方式:
前后端数据交互的加密方式主要有两种:对称加密、非对称加密
简单说,对称加密前后端使用同一套密匙,加解密的效率要高得多,如果密匙泄露不安全。非对称加密是公钥加密,私钥解密,加密解密慢,实现复杂,相对安全。
非对称加密,常见的RSA加密,后端生成公钥和私钥,前端通过公钥给参数加密,后端通过私钥解密。
使用场景:QQ登录、游戏、客户端、管理系统等的登录。
后端生成公钥和私钥后,将公钥发给前端,前端使用公钥对用户名及密码进行加密,后端接收到后通过私钥进行解密。私钥是不放在网络上传播的。
(没有看到后端用私钥加密,前端公钥解密的,如果私钥不能加以传播,而又要使用非对称加密去做前后端加解密,当初领导非让实现非对称加解密就写了一个例子是后端用公钥加密,前端用私钥解密,前端用公钥加密,后端用私钥解密。其实是错的,加密必须要用公钥,解密必须用私钥,而私钥不能传播,所以此方式和对称加密没有什么区别可言了,仅仅是一把钥匙和两把钥匙的区别。后来领导说 他想错了…)
因为RSA 必须要生成一对公私钥,这个生成的过程时间长,一般只生成一次,所以你的私钥一旦泄露出去就不安全了
对称加密,常见的AES加密,后端生成一个密钥,告诉前端,前端通过该密钥进行加密,后端通过该密钥对前端传的加密数据进行解密;后端通过该密钥进行加密,前端通过该密钥对后端返回的加密数据进行解密。
如果觉得不安全,可以在每次建立连接的时候生成新的,就算一次泄露了,下次也是安全的,相比较,前端加密还是用对称加密好,每次的密钥可以让后端随机生成,而且效率高。
本身加密这种事意思意思就可以了,防小人不放君子。
参考文章:
非对称加密
API接口之对称加密、非对称加密(三)
RSA后台加密,前端解密
博客园的文章在审核
对称加密
对称加密和非对称加密(一)初步理解
前后端分离API接口如何加密 —— AES加密方案
AES加密算法的详细介绍与实现
【安全与协议】使用crypto.js进行加密详解
错误理论实现的demo(后端公钥加密,前端私钥解密)
采用RSA加密解密
流程:
1.服务端生成公钥和私钥,私钥发给前端,公钥服务端自己保存
2.服务端使用公钥加密
3.前端使用私钥解密
前端代码:
https://github.com/zhi-re/vue-start.git
后端提供的非对称加密接口:
http://api.zhire.cc/jupiter/i/box/list2?query_type=1&query_date=2021-02-01
非对称其实和对称没啥区别,对称加密是前后端使用一样的钥匙,非对称加密就是前后端的钥匙不一样…
项目下载下来 启动后点这个就可以了 其他的菜单是引入的饿了么的ui 有bug 样式不展示 不用管。
// 后端代码:
@Slf4j
public class RsaUtils {
//生成秘钥对
public static KeyPair getKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
/**
* 私钥匙加密或解密
*
* @param content
* @param privateKeyStr
* @return
*/
public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {
// 私钥要用PKCS8进行处理
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
KeyFactory keyFactory;
PrivateKey privateKey;
Cipher cipher;
String text = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
// 还原Key对象
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(opmode, privateKey);
//加密解密操作
text = encryptTxt(opmode, cipher, content);
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
/**
* 公钥匙加密或解密
*
* @param content
* @return
*/
public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {
// 公钥要用X509进行处理
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
KeyFactory keyFactory;
PublicKey publicKey;
Cipher cipher;
String text = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
// 还原Key对象
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(opmode, publicKey);
//加密解密操作
text = encryptTxt(opmode, cipher, content);
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
public static String encryptTxt(int opmode, Cipher cipher, String content) {
byte[] result;
String text = null;
try {
if (opmode == Cipher.ENCRYPT_MODE) { // 加密
result = cipher.doFinal(content.getBytes());
text = Base64.encodeBase64String(result);
} else if (opmode == Cipher.DECRYPT_MODE) { // 解密
result = cipher.doFinal(Base64.decodeBase64(content));
text = new String(result, "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
/**
* 1.服务端生成公钥和私钥,私钥发给前端,公钥服务端自己保存
* 2.服务端使用公钥加密
* 3.前端使用私钥解密
*
* @param args
*/
public static void main(String[] args) {
try {
KeyPair keyPair = getKeyPair();
PrivateKey pairPrivate = keyPair.getPrivate();
PublicKey pairPublic = keyPair.getPublic();
// 公钥
String publicKey = Base64.encodeBase64String(pairPublic.getEncoded());
System.out.println("公钥:" + publicKey);
// 私钥
String privateKey = Base64.encodeBase64String(pairPrivate.getEncoded());
System.out.println("私钥:" + privateKey);
// 使用公钥加密
String content = "张三";
String txtByPublic = RsaUtils.encryptByPublicKey(content, publicKey, Cipher.ENCRYPT_MODE);
System.out.println("公钥加密结果:" + txtByPublic);
String txtByPrivate = RsaUtils.encryptByprivateKey(txtByPublic, privateKey, Cipher.DECRYPT_MODE);
System.out.println("私钥解密结果:" + txtByPrivate);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 前端代码:先引入jsencrypt.min.js
function decryptByRSA(content) {
if (content === null) return;
var encrypt = new JSEncrypt();
// 私钥
var priKey = 'XXXXXXX';
encrypt.setPrivateKey(priKey);
var result = encrypt.decrypt(content);
console.log("解密结果:", result);
return result;
}