vue 接口加密

引言

vue项目实现一个基本的接口加密非常简单,通过 axios 配合加密解密算法做请求、响应预处理。后端一样的操作,拦截器处理、网关处理也好,eBPF hook也罢,殊途同归。

接口加密的作用: 安全、防爬 等。悉知: 没有绝对安全的系统,只有破解成本的高低。

实现

首先创建一个vue项目,然后引入 axios、crypto-js

1
2
yarn add crypto-js
yarn add axios

前端目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.
├── README.md
├── index.html
├── package.json
├── public
│   └── vite.svg
├── src
│   ├── App.vue
│   ├── apis
│   │   └── httpdemo.js // 接口请求
│   ├── assets
│   │   └── vue.svg
│   ├── components
│   │   └── HelloWorld.vue // 测试的页面
│   ├── main.js
│   ├── style.css
│   └── utils
│   ├── AEScrypto.js //加解密方法
│   └── request.js // axios预处理
├── vite.config.js
└── yarn.lock

这篇文章主要是讲解思路,为了省事跟前面的文章 python RSA、AES 加密解密相关联,加密方法用AES的CBC padding7,别问为啥不用rsa,有长度限制。

AEScrypto.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import CryptoJS from 'crypto-js';

const secretKey = CryptoJS.enc.Utf8.parse('1234567812345678');
const iv = CryptoJS.enc.Utf8.parse('1234567812345678');

// 加密函数
export function encrypt(data) {
const encrypted = CryptoJS.AES.encrypt(data, secretKey, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return encrypted.toString();
}

// 解密函数
export function decrypt(encryptedData) {
const decrypted = CryptoJS.AES.decrypt(encryptedData, secretKey, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return decrypted.toString(CryptoJS.enc.Utf8);
}


// 使用示例
const originalData = 'Hello, World!';


const encryptedData = encrypt(originalData);
console.log('Encrypted Data: ', encryptedData);

const decryptedData = decrypt(encryptedData);
console.log('Decrypted Data: ', decryptedData);

request.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import axios from 'axios'
import {encrypt, decrypt} from './AEScrypto.js'
const service = axios.create({
baseURL: 'http://127.0.0.1:8002',
timeout: 5000
})


service.interceptors.request.use(
config => {
console.log("明文请求体: ",config.data)
const encryptData = encrypt(JSON.stringify(config.data))
console.log("密文消息体: ", encryptData)
config.data = {
"req": encryptData
}
return config;
}
)

service.interceptors.response.use(
response => {
console.log("密文响应体: ",response.data)
const decryptData = JSON.parse(decrypt(response.data))
console.log("明文消息体: ", decryptData)
response.data = decryptData
return response;
}
)

export default service;

httpdemo.js

1
2
3
4
5
6
7
8
9
10
import request from "../utils/request.js";

export function helloWordApi(data){
return request({
url: 'hello',
method: "POST",
data: data
})
}

HelloWorld.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<template>
<h1>{{ msg }}</h1>
<input type="text" v-model="req_body">
<button @click="reqHello">请求api</button>
<div class="code">
请求体-明文<br>
{{req_body}} <br>
响应体-明文<br>
{{res_body}} <br>
</div>
</template>

<script setup>
import { ref } from 'vue'
import {helloWordApi} from "../apis/httpdemo.js";

defineProps({
msg: String,
})

const req_body = ref()
const res_body = ref()
function reqHello(){

console.log('req_body', req_body.value)
const api_data = JSON.parse(req_body.value)
helloWordApi(api_data).then(
res=>{
res_body.value = res.data
console.log('res_body', res_body.value, typeof res.data)
}
)
}


</script>

<style scoped>
.code{
background-color: #888888;
}
</style>

后端我省事使用flask写,跟前篇的charles自定义解密插件文章同理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# time : 2023/11/7
# __author__ = ysc
import json
import time

from flask import Flask, request
from flask_cors import CORS

from AESCipherUtils import AESCipher

app = Flask(__name__)
CORS(app)
aes = AESCipher()

@app.route('/hello', methods=['GET','POST'])
def hello():
# body 中的req 为加密后的密文
print("req body: ", request.json)
res = json.loads(aes.decrypt(request.json['req']))
res['timestamp'] = int(time.time())
res = aes.encrypt(json.dumps(res))
# 加一个时间戳,加密后返回
print("res body: ", res)
return res

@app.route('/decrypt', methods=['POST'])
def decrypt():
data = {}

req_body_json = request.json
try:
data['req'] = aes.decrypt(req_body_json['req'])
data['res'] = aes.decrypt(req_body_json['res'])

except Exception as error:
data['error'] = str(error)
return data


if __name__ == '__main__':
app.run(
port=8002,
host="0.0.0.0",
debug=True
)

逻辑非常简单,axios 将密文请求体加密组装成 {"req":"加密后的密文"} 放在body中进行请求,后端解密后加个时间戳(模仿业务处理),加密返回。axios再对响应进行预处理。

演示

效果图

  • 本文作者: Ysc Test
  • 本文链接: https://ysctest.cn/posts/ddf91364.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 法律声明: 本博客提供的所有包括但不限于(文章和API)等服务,仅用于学习,技术分享、交流。不得用于违法犯罪、损害国家利益。非法使用者本站不承担任何法律责任,并且本站保留追究其法律责任的权力!!!