本文介绍前后端数据加密传输的一种方案,后台用Python3编写,前端用Vue编写,数据采用AES加密算法,模式用ECB,padding用pkcs7。
一、后台实现
后台用python编写,使用Crypto库
- 安装AES加解密库
pip install Crypto
安装后如果提示:ModuleNotFoundError: No module named ‘Crypto’,把安装目录下包含crypto的改成Crypto,如图:
- python代码
from Crypto.Cipher import AES
import base64
import binascii
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
class CAesEcbPkcs7:
def __init__(self, key: str):
self.BLOCK_SIZE = 16
key = key[0:16] if len(key) >= 16 else key + (16 - len(key)) * '0' # key长度超过16的丢弃;不足16位的补0
self.key = key.encode('utf-8')
self.mode = AES.MODE_ECB
self.cryptor = AES.new(self.key, self.mode)
def pkcs7_decode(self, bstr: bytes):
val = bstr[-1]
# print('val = ', val)
if val > self.BLOCK_SIZE:
raise ValueError('Input is not padded or padding is corrupt')
n = len(bstr) - val
return bstr[:n]
def pkcs7_encode(self, bstr: bytes):
n = len(bstr)
output = StringIO()
val = self.BLOCK_SIZE - (n % self.BLOCK_SIZE)
for _ in range(val):
output.write('%02x' % val)
return bstr + binascii.unhexlify(output.getvalue())
def encrypt(self, text: str):
text = text.encode('utf-8')
pad_text = self.pkcs7_encode(text)
msg = self.cryptor.encrypt(pad_text)
encode_msg = base64.b64encode(msg)
return encode_msg.decode("utf-8")
def decrypt(self, text: str):
plain_text = self.cryptor.decrypt(base64.b64decode(text))
plain_text = self.pkcs7_decode(plain_text)
return plain_text.decode(encoding='utf-8')
if __name__ == '__main__':
aes = CAesEcbPkcs7('t7CLWhtUTAgAFbw0')
enstr = aes.encrypt('hello world')
str1 = aes.decrypt(enstr)
print('enstr = ', enstr) # IlphHBX6JENV1iW09ZW2Tg==
print('str1 = ', str1, len(str1))
str1 = aes.decrypt('XshGNjhFV+qXVUOFtxnNDYNNzcDlR7r4NoMVId1nGuU=')
print('str1 = ', str1, len(str1))
二、前端实现
前端用vue实现,使用crypto-js库
- 安装AES加解密库
npm install --save crypto-js
- vue代码
<template>
<div class="container">
测试AES加解密特性
</div>
</template>
<script>
import CryptoJS from 'crypto-js'
export default {
name: 'vueaes',
props: {
msg: String
},
components: {
},
data() {
return {
key: 't7CLWhtUTAgAFbw0'
}
},
mounted: function() {
let enstr = this.encrypt('hello 你好 world!');
let str = this.decrypt(enstr);
console.log('enstr = ', enstr);
console.log('str = ', str);
},
methods: {
encrypt(word, keyStr) {
keyStr = keyStr ? keyStr : this.key;
var key = CryptoJS.enc.Utf8.parse(keyStr);
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
},
//解密
decrypt(word, keyStr) {
keyStr = keyStr ? keyStr : this.key;
var key = CryptoJS.enc.Utf8.parse(keyStr);
var decrypt = CryptoJS.AES.decrypt(word, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}
}
}
</script>
<style>
</style>
三、代码测试
- 后端用字符串:“验证python3加密,VUE解密的功能!”
- 前端和后端AES密钥:123456
后台加密:
aes = CAesEcbPkcs7('123456')
enstr = aes.encrypt('验证python3加密,VUE解密的功能!')
str1 = aes.decrypt(enstr)
print('enstr = ', enstr)
print('str1 = ', str1)
运行结果
后台生成加密字符串:ikXKp688lxaub7gLhr9cmcv+crzMkU3nNKoaiVCiuJtlqAX3HSruoSH9kAnlZ4/1
前端解密:
let enstr = 'ikXKp688lxaub7gLhr9cmcv+crzMkU3nNKoaiVCiuJtlqAX3HSruoSH9kAnlZ4/1';
let str = this.decrypt(enstr, '1234560000000000');
console.log('enstr = ', enstr);
console.log('str = ', str);
运行结果:
重要说明:后台设置的密钥是123456,由于密钥长度要有16位,不足就补0,所以实际的密钥是1234560000000000,前端用123456做密钥会报错