第一个项目
项目描述:通过RSA对前后端传输的数据进行加密解密,前端通过公钥进行加密,Java后端通过私钥进行解密。
薛雄辉/springbootdemo - Gitee.com
Java后端
4.0.0
com.demo
rsa
0.0.1-SNAPSHOT
jar
rsa
java与node.js非对称加密
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
org.springframework.boot
spring-boot-starter-test
test
org.bouncycastle
bcpkix-jdk15on
1.60
org.springframework.boot
spring-boot-maven-plugin
控制层
package com.demo.rsa;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import javax.crypto.Cipher;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* java前后端分离非对称加密数据传输
*
*/
@RestController
public class MainController {
/**
* 存储用户信息
*/
private Map users = new ConcurrentHashMap<>();
/**
* 存储session私钥
*/
private Map session = new ConcurrentHashMap<>();
static {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
/**
* 根据token获取用户的信息
* @param token
* @return
*/
@GetMapping("getUser")
public String getUser(@RequestHeader(value = "Authorization", required = false) String token) {
if (token == null) {
return null;
}
return users.containsKey(token) ? users.get(token) : null;
}
/**
* 账号密码明文传输登陆
* @Deprecated 这个注解表示这个方法不推荐程序员使用,但是还可以使用
* @param params
* @return
*/
@PostMapping("login")
@Deprecated
public Map login(@RequestBody Map params) {
Map result = new HashMap<>();
if (!params.containsKey("account") || !params.containsKey("password")) {
result.put("success", false);
result.put("message", "请输入账号和密码");
return result;
}
if (!"123456".equals(params.get("password"))) {
result.put("success", false);
result.put("message", "密码错误");
return result;
}
String token = UUID.randomUUID().toString();
users.put(token, params.get("account"));
result.put("success", true);
result.put("message", "登录成功");
result.put("data", token);
return result;
}
/**
* 获取session公钥
*
* @return
*/
@GetMapping("getSession")
public Map getSession() throws Exception {
String sessionId = UUID.randomUUID().toString();
Map result = new HashMap<>();
result.put("sessionId", sessionId);
String algorithm = "RSA";
String privateKey = null, publicKey = null;
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(algorithm);
keyPairGen.initialize(512);
KeyPair keyPair = keyPairGen.generateKeyPair();
byte[] encoded = keyPair.getPrivate().getEncoded();
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(encoded);
ASN1Encodable encodable = pkInfo.parsePrivateKey();
ASN1Primitive primitive = encodable.toASN1Primitive();
byte[] privateKeyPKCS1 = primitive.getEncoded();
PemObject pemObject = new PemObject("RSA PRIVATE KEY", privateKeyPKCS1);
try (StringWriter stringWriter = new StringWriter()) {
try (PemWriter pemWriter = new PemWriter(stringWriter)) {
pemWriter.writeObject(pemObject);
pemWriter.flush();
String pemString = stringWriter.toString();
privateKey = pemString;
}
}
encoded = keyPair.getPublic().getEncoded();
SubjectPublicKeyInfo spkInfo = SubjectPublicKeyInfo.getInstance(encoded);
primitive = spkInfo.parsePublicKey();
byte[] publicKeyPKCS1 = primitive.getEncoded();
pemObject = new PemObject("RSA PUBLIC KEY", publicKeyPKCS1);
try (StringWriter stringWriter = new StringWriter()) {
try (PemWriter pemWriter = new PemWriter(stringWriter)) {
pemWriter.writeObject(pemObject);
pemWriter.flush();
String pemString = stringWriter.toString();
publicKey = pemString;
}
}
// 记录私钥
session.put(sessionId, privateKey);
// 返回公钥
result.put("publicKey", publicKey);
return result;
}
/**
* 加密后的前端数据进行登陆
* @param params
* @return
*/
@SuppressWarnings("unchecked")
@PostMapping("loginByEncrypt")
public Map loginByEncrypt(@RequestBody Map params) {
Map result = new HashMap<>();
if (!params.containsKey("sessionId")) {
result.put("success", false);
result.put("message", "sessionId是必填参数");
return result;
}
if (!params.containsKey("playload")) {
result.put("success", false);
result.put("message", "playload是必填参数");
return result;
}
String sessionId = params.get("sessionId");
if (!session.containsKey(sessionId)) {
result.put("success", false);
result.put("message", "无效session");
return result;
}
Map json = null;
try {
String privateKey = session.get(sessionId);
String playload = params.get("playload");
String text = decrypt(playload, privateKey);
ObjectMapper mapper = new ObjectMapper();
json = mapper.readValue(text, Map.class);
} catch (Exception e) {
e.printStackTrace();
}
if (json == null) {
result.put("success", false);
result.put("message", "非法请求");
return result;
}
if (!json.containsKey("account") || !json.containsKey("password")) {
result.put("success", false);
result.put("message", "请输入账号和密码");
return result;
}
if (!"123456".equals(json.get("password"))) {
result.put("success", false);
result.put("message", "密码错误");
return result;
}
String token = UUID.randomUUID().toString();
users.put(token, json.get("account"));
result.put("success", true);
result.put("message", "登录成功");
result.put("data", token);
return result;
}
/**
* 私钥解密
*
* @param text
* @param privateKey
* @return
* @throws Exception
*/
private String decrypt(String text, String privateKey) throws Exception {
String algorithm = "RSA";
String keyText = privateKey.split("-----")[2].replaceAll("\n", "").replaceAll("\r", "");
byte[] bytes = Base64.decode(keyText.getBytes());
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(bytes);
PrivateKey key = keyFactory.generatePrivate(privateKeySpec);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(Base64.decode(text));
return new String(doFinal, "utf-8");
}
}
Vue前端
使用Vue脚手架搭建项目
vue init webpack demo-rsa
npm install
npm install --save axios
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api'
new Vue({
el: '#app',
router,
components: {
App
},
template: ' '
})
路由配置文件
import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/components/Main'
import Login from '@/components/Login'
Vue.use(Router)
let routes = [{
path: '/',
name: '首页',
component: Main
},
{
path: '/login',
name: '登录',
component: Login
}
]
const router = new Router({
routes: routes
})
router.beforeEach((to, from, next) => {
if (to.path == '/login') {
sessionStorage.removeItem('Authorization')
}
let token = sessionStorage.getItem('Authorization')
if (!token && to.path != '/login') {
next({
path: '/login'
})
return
}
next()
})
export default router;
router/index.js
登录页
用户名:
密码:
{{message}}
登录后的页面
当前用户:{{user}}
components/Main.vue
设置开发跨域
proxyTable: {
'/api': {
target: 'http://localhost:8080/',
changeOrigin: true,
pathRewrite: {
'^/api': '/'
}
}
}
第二个项目:前后端都加密的解决方案
前后端RSA互相加解密、加签验签、密钥对生成(Java)_前后端rsa加解密_凌波漫步&的博客-CSDN博客