# ASCII编码 GBK unicode utf8(针对ASCII一个字节,针对汉字三个字节)
from urllib import parse
# 值编码
value = parse.quote('&&222==333')
print(value)
# 键值编码
data = {'wd':'&&7www', 'name':'小黑'}
print(parse.urlencode(data))
%26%26222%3D%3D333
wd=%26%267www&name=%E5%B0%8F%E9%BB%91
import base64
s = '#!$'
print(s.encode())
print(bin(ord('#')))
print(bin(ord('!')))
print(bin(ord('$')))
# 001000 110010 000100 100100
# 8 50 4 36 ========> I y E k
ret = base64.b64encode(s.encode())
print(ret.decode())
b’#!$’
0b100011
0b100001
0b100100
IyEk
import base64
print('++++++++++++++案例1+++++++++++++')
# base64编码后结果
ret = 'IyEkPQ=='
# base64解码
ret = base64.b64decode(ret)
print(ret.decode())
print('++++++++++++++案例2+++++++++++++')
# 案例2
s = 'you!'
ret = base64.b64encode(s.encode())
print(ret.decode())
print(base64.b64decode(ret))
++++++++++++++案例1+++++++++++++
#!$=
++++++++++++++案例2+++++++++++++
eW91IQ==
b’you!’
from Crypto.PublicKey import RSA
# 构建RSA算法对象
rsakey = RSA.generate(1024)
# 生成公钥
# print('公钥:', rsakey.public_key().exportKey())
with open('rsa.public.pem', 'wb') as f:
f.write(rsakey.public_key().exportKey())
# 生成私钥
with open('rsa.private.pem', 'wb') as f:
f.write(rsakey.exportKey())
# print('私钥:', rsakey.exportKey())
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
data = 'alex is a monkey!'
# rsa: 公钥加密私钥解密,用于数据加密
# rsa: 私钥加密公钥解密,用于数字签名
with open('rsa.public.pem', 'r') as f:
pk = f.read()
# 获取公钥对象
rsa_pk = RSA.importKey(pk)
# 获取rsa算法对象
rsa = PKCS1_v1_5.new(rsa_pk)
# 基于rsa进行加解密
encrypt_data = rsa.encrypt(data.encode())
print('encrypt_data:', encrypt_data)
# 为了在网络中正确传输,进行一个base64封装
base64_encrypt_data = base64.b64encode(encrypt_data)
print('base64编码:', base64_encrypt_data.decode())
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
base64_encrypt_data = 'luWJ/+VE2DAMnTCk6ewOTUGc3Qkx0W4TIEtFGlCvr2dBNkbyiZvVMGHFcE+8p6/x+/saD0is='
# base解码
encrypt_data = base64.b64decode(base64_encrypt_data)
print('encrypt_data:', encrypt_data)
# 解密
with open('rsa.private.pem', 'r') as f:
prikey = f.read()
# 生成钥匙对象
rsa_pk = RSA.importKey(prikey)
# 生成算法对象
rsa = PKCS1_v1_5.new(rsa_pk)
# 解密
data = rsa.decrypt(encrypt_data, None)
print('解密原数据:', data)
# 摘要算法 md5
from hashlib import md5, sha1, sha256, sha512
data = '123'
m = md5('yuanlaoshidashuaige'.encode())
m.update(data.encode())
print(m.hexdigest())
# 总结: 摘要算法
# (1) 不可逆
# (2) 相同值计算结果必相同
# (3) 不同值计算长度固定,内容不固定
# 摘要算法应用
# 数据库加密
# AES对称加密
# 先加密,再base64编码
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
# 原文数据,必须是16的倍数
data = 'alex is a monkey!'
data = pad(data.encode(), block_size=16)
print(data)
key = 'asdfghjkl1234567'.encode() # 必须是16字节
iv = '1234567890abcdef' .encode() # 必须是16字节
aes = AES.new(key=key, mode=AES.MODE_ECB)
aes = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
# 基于aes算法对象对数据做加密
encrypt_data = aes.encrypt(data)
print('ase加密:', encrypt_data)
# base64编码
b64encode_encrypt_data = base64.b64encode(encrypt_data)
print(b64encode_encrypt_data.decode())
b’alex is a monkey!\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f’
ase加密: b’\xa8\x05\x9c\xaa5\xe2P1\xaamb\xc8\xdc\xb5\x12|\x93\xbbA<\xec\xf5\x94\x95n\xb0=B\x17\xf5\xa1p’
qAWcqjXiUDGqbWLI3LUSfJO7QTzs9ZSVbrA9Qhf1oXA=
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
b64encode_encrypt_data = 'qAWcqjXiUDGqbWLI3LUSfJO7QTzs9ZSVbrA9Qhf1oXA='
print('base64编码: ', b64encode_encrypt_data, '准备进行base64解码')
# 先进行base64解码
encrypt_data = base64.b64decode(b64encode_encrypt_data)
print('encrypt_data:', encrypt_data, '准备进行AES的CBC解密')
# aes解密
key = 'asdfghjkl1234567'.encode() # 必须是16字节
iv = '1234567890abcdef' .encode() # 必须是16字节
aes = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
ret = aes.decrypt(encrypt_data)
print('解密结果:', ret, '准备去除填充')
# 去除填充
ret = unpad(ret, block_size=16)
print('去除填充后:', ret)
base64编码: qAWcqjXiUDGqbWLI3LUSfJO7QTzs9ZSVbrA9Qhf1oXA= 准备进行base64解码
encrypt_data: b’\xa8\x05\x9c\xaa5\xe2P1\xaamb\xc8\xdc\xb5\x12|\x93\xbbA<\xec\xf5\x94\x95n\xb0=B\x17\xf5\xa1p’ 准备进行AES的CBC解密
解密结果: b’alex is a monkey!\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f’ 准备去除填充
去除填充后: b’alex is a monkey!’
// 获取四大名著
// js代码 JS:事件驱动
var dom = document.getElementsByTagName("p")[1]
function get_page_books (page) {
// 查询参数
var params = {
'page':page.toString()
}
// 数据加密 aes-128
function encrypt_data(data){
// AES算法
var key = CryptoJS.enc.Utf8.parse('0123456789abcdef');
var iv = CryptoJS.enc.Utf8.parse('0123456789abcdef');
// 待加密数据
var plaintext = JSON.stringify(data);
// 进行AES-128加密,使用CBC模式和PKCS7填充
var encrypted = CryptoJS.AES.encrypt(
plaintext, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
// 获取加密后密文
var ciphertext = encrypted.toString()
return ciphertext
}
var sign = encrypt_data(params);
params.sign = sign;
// 发送发ajax,应该JS的代码,但是JS
$.ajax({
url: "http://127.0.0.1:5000/books",
type: "get",
data: params,
success: function (res) {
console.log("res:::", res)
// dom
var p3 = $("p").eq(-1)
p3.html(res.map(item=>`【${item}】`))
}
})
}
比对加密结果是否正确,如果正确则认定为正常用户请求,返回数据给前端正常数据,否则不返回数据。
def verify_sign(params, sign):
try:
# base64编码
encrypt_data = base64.b64decode(sign)
# AES解密,key,iv必须为16字节
key = '0123456789abcdef'.encode()
iv = '0123456789abcdef'.encode()
aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
data = aes.decrypt(encrypt_data)
data = unpad(data, 16)
print('解密成功')
res = json.loads(data.decode())
if res == params:
print('比对成功!!请进')
return True
print('比对失败!')
except Exception as e:
print('解密报错', e)
return False
@app.get("/books")
def get_books():
# 查询参数
params = request.args.to_dict()
# 校验sign值
if 'sign' not in params:
return jsonify(['非法入侵!!滚出去'])
sign = params.pop('sign')
verify = verify_sign(params, sign)
if not verify:
return jsonify(['非法入侵!!滚出去'])
page_num = int(params.get('page', 1))
books = ["聊斋志异", "金瓶梅", "国色天香", "剪灯新话", "西游记", "三国演义", "水浒传", '大黑驴', '小黑驴', '宿舍黑驴']
# random_books = random.sample(books, 4)
start_index = (page_num - 1) * 2
end_index = page_num * 2
page_book_list = books[start_index:end_index]
return jsonify(page_book_list)
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import json
url = 'http://127.0.0.1:5000/books'
# 进行base64编码
for i in range(1, 6):
param = {"page":str(i)}
# json.dumps一定要去除空格
s = json.dumps(param, separators=(',', ':'))
# 填充,以便准备进行AES.CBC加密算法
s = pad(s.encode(), block_size=16)
#print(s)
# 进行AES加密
key = '0123456789abcdef'
iv = '0123456789abcdef'
# 构造AES对象
aes = AES.new(key=key.encode(), iv=iv.encode(), mode=AES.MODE_CBC)
s = aes.encrypt(s)
#print(s)
encrypt_data = base64.b64encode(s)
# 构造请求参数
param['sign'] = encrypt_data.decode()
# 发送请求
response = requests.get(url=url, params=param)
print(response.json())
坑了小黑好长时间的bug,python中为了美化,序列化结果多加了一个空格:‘{“小黑黑”: “爱你哟”}’ ,而js序列号的结果是:‘{“小黑黑”:“爱你哟”}’ ),导致其json.dumps序列化结果与JS中JSON.stringify不一致,所以导致加密后对比失败!!!小黑通过调试了俩小时才发现(),解决方法是dumps函数中加入参数separators=(‘,’, ‘:’)