常见加密方式:
加密:
前端{
1.把加密的数据给后端
2.JS加密
3.携带正确的参数——进行加密}
后端:存入数据库或者校验
为了反爬,前端请求就会进行携带指定的参数,参数的值会进行加密,后端再进行校验
1.MD5加密
概念:线型散列算法(签名算法)
加密:产生一个固定长度的十六进制的数据(32位或16位)
解密:常规的说法:MD5是不存在解密的(不可解密)。
理论上可以破解——暴力破解,逐个比对,轮询,但需要庞大的数据量、长时间、高性能机器。
JS如何进行MD5加密?
压缩文件:命名符合规范,就会有min
https://cdn.bootcss.com/blueimp-md5/1.1.0/js/md5.min.js
未压缩文件:https://cdn.bootcss.com/blueimp-md5/1.1.0/js/md5.js
开发阶段选择未压缩文件,可读性强,部署阶段用压缩文件,节约空间
JS实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MD5</title>
</head>
<body>
<script type="text/javascript" src="http://cdn.bootcss.com/blueimp-md5/1.1.0/js/md5.min.js"></script>
<script type="text/javascript">
//MD5加密
var sign = md5('123456')
console.log(sign)
</script>
</body>
</html>
python实现:
from hashlib import md5
def md5_encryption(code):
'''
md5加密——方法返回对象
:param code: str类型,要加密的字符串
:return:str:返回加密后的字符串
'''
md = md5() #实例化——得到MD5加密对象
md.update(code.encode()) #生成加密数据
return md.hexdigest() #获取加密数据
if __name__ == '__main__':
sign = md5_encryption('123456')
print(sign,len(sign))
实例:有道翻译JS逆向(MD5)
需求:抓取有道的接口,实现翻译的功能
步骤:
1.参数分析步骤
(1)ctrl+shift+f全局搜索参数字段
(2)逐个分析
(3)拆解:假设、验证,console ,断点进行参数查看
2.python实现
spider.py
import scrapy
from time import time
import random
from hashlib import md5
class YoudaoSpider(scrapy.Spider):
name = 'youdao'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule',]
def start_requests(self):
# 获取查询单词
word = input('请输入你要查询的单词:')
# 获取当前时间戳
lts = str(int(time() * 1000))
# 获取salt
salt = lts + str(random.randint(0, 9))
# 获取sign
sign = "fanyideskweb" + word + salt + "Y2FYu%TNSbMCxc3t2u^XT"
md = md5() # 实例化——得到MD5加密对象
md.update(sign.encode()) # 生成加密数据
sign = md.hexdigest()
post_data = {
'i': word,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': salt,
'sign': sign,
'lts': lts,
'bv': '679a714475741baa9769e4725c532bb7',
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME',
}
# 将cookie转成字典类型
cookies = 'OUTFOX_SEARCH_USER_ID=1370777476@2409:8920:400:46ac:a171:61b:7868:1c32; OUTFOX_SEARCH_USER_ID_NCOO=1092215250.8540661; UM_distinctid=179d34a1f154d-057d5ca47388f3-6701b35-144000-179d34a1f161e3; JSESSIONID=aaap-S9l5WclRfOMVkgQx; ___rl__test__cookies='+lts
cookies = {i.split('=')[0]: i.split('=')[1] for i in cookies.split('; ')}
print(post_data)
# 手动发送post请求
yield scrapy.FormRequest(url = self.start_urls[0],
headers={
'Host': 'fanyi.youdao.com',
'Origin': 'https://fanyi.youdao.com',
'Referer': 'https://fanyi.youdao.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36',
},
formdata=post_data,
callback=self.parse,
cookies = cookies)
def parse(self, response):
print(response,response.text)
2.DEF/AES加密
概念:对称性加密算法
DES加密:
from Cryptodome.Cipher import DES
import binascii
from time import time
import random
class MyDESCipher:
def __init__(self,key,iv):
self.key = key
self.iv = iv
def encryption(self,data):
'''
:param data:
:return:
'''
cipher = DES.new(self.key,DES.MODE_CFB,self.iv)
data = data.encode()
return binascii.b2a_hex(cipher.encrypt(data))
def decryption(self,data):
'''
解密
:param data:十六进制转二进制
:return:
'''
data = binascii.a2b_hex(data)
cipher =DES.new(self.key,DES.MODE_CFB,self.iv)#创建相同的规则
return cipher.decrypt(data).decode()
if __name__ == '__main__':
#需要加密的数据
word = 'hello world'
lts = str(int(time() * 1000)) # 获取当前时间戳
salt = lts + str(random.randint(0, 9)) # 获取salt
sign = "fanyideskweb" + word + salt + "Y2FYu%TNSbMCxc3t2u^XT" # 获取sign
# 秘钥
key = b'maquYIGE'
iv = b'12345678'
myDEFCipher = MyDESCipher(key,iv)
res = myDEFCipher.encryption(sign)
print(res)
data = myDEFCipher.decryption(res)
print(data)
AES加密:
from Cryptodome import Random
from Cryptodome.Cipher import AES
import binascii
from time import time
import random
class MyAESCipher:
def __init__(self,key,iv):
self.key = key
self.iv = Random.new().read(AES.block_size)
def encryption(self,data):
'''
:param data:
:return:
'''
cipher = AES.new(self.key,AES.MODE_CFB,self.iv)
data = data.encode()
return binascii.b2a_hex(cipher.encrypt(data))
def decryption(self,data):
'''
解密
:param data:十六进制转二进制
:return:
'''
data = binascii.a2b_hex(data)
cipher =AES.new(self.key,AES.MODE_CFB,self.iv)#创建相同的规则
return cipher.decrypt(data).decode()
if __name__ == '__main__':
#需要加密的数据
word = 'hello world'
lts = str(int(time() * 1000)) # 获取当前时间戳
salt = lts + str(random.randint(0, 9)) # 获取salt
sign = "fanyideskweb" + word + salt + "Y2FYu%TNSbMCxc3t2u^XT" # 获取sign
# 秘钥,偏移向量(16位)
key = b'maquYIGEmaquYIGE'
#iv = Random.new().read(AES.block_size)
myAESCipher = MyAESCipher(key,iv)
res = myAESCipher.encryption(sign)
print(res)
data = myAESCipher.decryption(res)
print(data)
3.RSA加密
概念:非对称性加密算法
两个秘钥,分为秘钥:公钥和私钥,私钥由公钥计算得到。
公钥对数据进行加密,只有使用对应的私钥才能解密。
优点:算法复杂
缺点:比对称加密慢
import rsa
import binascii
def rsa_encrypt(rsa_n,rsa_e,data):
#公钥
key = rsa.PublicKey(rsa_n,rsa_e)
res = rsa.encrypt(data.encode(),key)
return binascii.b2a_hex(res)
public_n = '30819f300d06092a864886f70d010101050003818d0030818902818100b231a2588df3a48d614084d22124b409076cbc386dc1dd877ca01bffddedd41a519ac83537dacaf7b797c2a9e4200bce661dc433e856963f928b1e4022d3a875fbe68a796c049a6df721e16c035e58936f0476279bed93129cc39768788dd48761df8e45c8eb2a9fe0bcab4ee9226d524a28c9a60878878fbdcca8bb344fb6a10203010001'
public_e = '10001' #一般都是这个
#把16进制数据转整数
rsa_n = int(public_n,16)
rsa_e = int(public_e,16)
data = 'hello world'
print(rsa_encrypt(rsa_n,rsa_e,data))
自定义加密方式
import rsa
import binascii
def rsa_encrypt(rsa_n,rsa_e,data):
#公钥
key = rsa.PublicKey(rsa_n,rsa_e)
res = rsa.encrypt(data.encode(),key)
return binascii.b2a_hex(res)
public_n = '30819f300d06092a864886f70d010101050003818d0030818902818100b231a2588df3a48d614084d22124b409076cbc386dc1dd877ca01bffddedd41a519ac83537dacaf7b797c2a9e4200bce661dc433e856963f928b1e4022d3a875fbe68a796c049a6df721e16c035e58936f0476279bed93129cc39768788dd48761df8e45c8eb2a9fe0bcab4ee9226d524a28c9a60878878fbdcca8bb344fb6a10203010001'
public_e = '10001' #一般都是这个
#把16进制数据转整数
rsa_n = int(public_n,16)
rsa_e = int(public_e,16)
data = 'hello world'
print(rsa_encrypt(rsa_n,rsa_e,data))