Asymmetric data encryption is implemented using JsENCRYPT and AXIOS
This is the 8th day of my participation in Gwen Challenge
background
You do not want the data sent by the application to be seen in Devtools. This prevents the interface from being stripped down by peers and then used maliciously
To avoid this problem, the first thought is to encrypt the transmitted data once and let the back end decrypt and process it
Although the JS source code is open to the browser, it is not difficult to locate the object code without the source map after being obfuscated by the build tool
The expected encrypted transmission is as follows
Description of encryption scheme
Symmetric encryption
Symmetric encryption means that both sides have the same secret key and both sides know how to encrypt and decrypt the ciphertext.
This is all well and good, but the problem is getting both parties to know the key.
Because the data is transmitted through the network, if the secret key is transmitted through the network, once the secret key is captured, there is no encryption significance
Asymmetric encryption
There are public and private keys:
- Public key The owner can know that data can be encrypted with a public key, but data must be decrypted using a private key
- The private key is known only to the party that distributes the public key
This encryption method can perfectly solve the problems of symmetric encryption
By comparison, the asymmetric encryption scheme with good confidentiality is selected as the encryption scheme
RSA symmetric encryption algorithm is used in this paper
Public and Private Key Generation
According to baidu experience, generate a 1024 bit secret key
Git Bash is recommended for Windows
The private key
openssl genrsa -out rsa_1024_priv.pem 1024
Copy the code
Click to view generating private key
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQC0YiWffUFPnr2OyfcaM8QLkdq30VQxjIctZJX/CnYn7NorwCyK
iBX3hULSUrBxBACZBtfeGtpT+I9yn3+6s4kClZiJNOOP8bvJab4fboLUtJt9XciK
ENRxHVcnrYMrM+0diXGH/COjeA7ym/L2M/eX1fxpZjTByaJdx0FZAlrD4wIDAQAB
AoGBAKarxU2vw4gZCdeE3/BzAmMaWrjcD2pVCZY0ya/Fb9WGMTSZtc4u3fU+Sbbi
tqtGYnMC8rUDpNZP5eOoYrIVL7MJFj7n5DIT6TJOxWRavWsei812pQlc6ccR/VEH
o0nN5JQRZH8DC+CE86QddOW7VfnRMIP4A7j8UEEiRxsPITExAkEA4N10W/HA7lYE
WKSRES4/gAJHg7cqS2dAWIovX/JtxzUyK2q50rWjbgbXXOGriIp3cRJeH2Jmi6tm
jQQ+ldWAqwJBAM1b/9cRLWJ6fPdDIjbrc9IQE6C5HYI0FsHuyCn3zUKnD1+hc7k5
+BrSpyG5VzdPH3WOhm6GJ5TCf/LlxvvIeakCQQCEO1Ywt2KYBTc7FVNFgifPVAfP
+gdCHi6lomUni/1oVuzwwSsTMMMxcY51zTM88Qg6Eu4MkKXy3lFI/cT8AXhPAkEA
vy4q27muGsQVmsvxClfgl2tIGpS7l/+OQDVgO1Hq0WZdtZXE+mexRqdd2NOHEoKi
svpgxHw4VRFNtH+d48EbIQJBAMcLRGOuUrPhyYXmvEvvGGqcFH7zwjoyYlQQYR3a
IeAC4Mo/vDo7agLXvlRFXgPWMXAJqzjVhZ+xmew4hUqe5HY=
-----END RSA PRIVATE KEY-----
Copy the code
The public key
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
Copy the code
Click to view the generated public key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0YiWffUFPnr2OyfcaM8QLkdq3
0VQxjIctZJX/CnYn7NorwCyKiBX3hULSUrBxBACZBtfeGtpT+I9yn3+6s4kClZiJ
NOOP8bvJab4fboLUtJt9XciKENRxHVcnrYMrM+0diXGH/COjeA7ym/L2M/eX1fxp
ZjTByaJdx0FZAlrD4wIDAQAB
-----END PUBLIC KEY-----
Copy the code
jsencrypt
- jsencrypt
- nodejs-jsencrypt
RSA encryption solution using Javascript
use
Install dependencies
# web
npm i jsencrypt
# node
npm i nodejs-jsencrypt
Copy the code
The introduction of
// web
import JSEncrypt from 'jsencrypt'
// node
const { JSEncrypt } = require('nodejs-jsencrypt')
Copy the code
Public key encryption method
// The above is automatically generated
const pubKey = 'Public key generated above'
function publicEncrypt(str){
const encrypt = new JSEncrypt()
encrypt.setPublicKey(pubKey)
return encrypt.encrypt(str)
}
Copy the code
Private key decryption method
const privKey = 'private key generated above'
function privDecrypt(str) {
const encrypt = new JSEncrypt()
encrypt.setPrivateKey(privKey)
return encrypt.decrypt(str)
}
Copy the code
You can see that the API is pretty neat
Use the sample
let str = publicEncrypt('hello world')
console.log(str)
console.log(privDecrypt(str))
Copy the code
Incorporate Axios practices
Axios configuration
npm i axios
Copy the code
The encryption logic is put into the Axios request interceptor, the original content is processed with json.stringify and then encrypted, and the encrypted content is passed using the value attribute, as shown below
import axios from "axios";
// Introduce the encryption method you just wrote
import { publicEncrypt } from "./utils/crypto";
const http = axios;
http.defaults.baseURL = '/api'
http.defaults.headers = {
"content-Type": "application/json"
};
// Request interceptor
http.interceptors.request.use(
config= > {
// Operate config before sending
// Encrypt the data passed
config.data = {
value:publicEncrypt(JSON.stringify(config.data))
}
return config;
},
err= > {
// Processing error
return Promise.reject(err); }); http.interceptors.response.use(response= > {
// Return before operation
return response.data;
},
err= > {
return Promise.reject(err); });export default http;
Copy the code
Server-side decryption sample code
Node.js is written directly using the HTTP module, and Express is written using the HTTP module.
- Decrypt the received content
- The decrypted content is returned directly
HTTP module example
The data event is used in conjunction with the End event to receive the passed data and then decrypt it back
const http = require('http')
// Introduce decryption methods
const { privDecrypt } = require('./utils/crypto')
const server = http.createServer((req, res) = > {
res.setHeader('content-type'.'application/json')
let buffer = Buffer.alloc(0)
// Receive the passed data
req.on('data'.(chunk) = >{
buffer = Buffer.concat([buffer, chunk])
})
req.on('end'.() = >{
try {
// Decrypt the passed data
const data = privDecrypt(JSON.parse(buffer.toString('utf-8')).value)
res.end(data)
} catch (error) {
console.log(error);
res.end('error')}})})/ / start
server.listen(3000.err= > {
console.log(`listen 3000 success`);
})
Copy the code
Express sample
Configure a front-facing * route, decrypt the passed content, and then rebind it to req.body for subsequent use by other routes
const express = require('express')
const { privDecrypt } = require('./utils/crypto')
const server = express()
server.use(express.urlencoded({ extended: false }))
server.use(express.json({ strict: true }))
// The first route to enter
server.route(The '*').all((req, res, next) = > {
console.log(`${req.method}--${req.url}`)
req.body = JSON.parse(privDecrypt(req.body.value))
next()
})
server.post('/test/demo'.(req,res) = >{
// Return directly to the actual content
res.json(req.body)
})
/ / start
server.listen(3000.err= > {
console.log(`listen 3000 success`);
})
Copy the code
Front-end code examples
Vite was used as a development preview tool
Vite. Config. js configuration: only request proxy is made, solving the development cross-domain problem
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:3000'.changeOrigin: true.rewrite: (path) = > path.replace(/^\/api/.' ')},}}}Copy the code
page
<body>
<button id="send">send</button>
<hr>
<h2></h2>
<textarea id="receive" placeholder="Received Contents"></textarea>
<script type="module" src="./index.js"></script>
</body>
Copy the code
logic
import $http from './http'
const $send = document.getElementById('send')
const $receive = document.getElementById('receive')
$send.addEventListener('click'.function(){
// Send a random content
$http.post('/test/demo', {name:'xm'.age: ~ ~ (Math.random()*1000)
}).then((res) = >[
updateReceive(res)
])
})
function updateReceive(data){
$receive.value = data instanceof Object?JSON.stringify(data):data
}
Copy the code
The results
page
Sending network Requests
Request response Content
Work done, access is very simple
Complete sample code repository
Welcome to comment and exchange