python爬虫之数据加密解密

Posted 人生如梦,亦如幻

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python爬虫之数据加密解密相关的知识,希望对你有一定的参考价值。

一、什么叫数据加密

  数据加密是指利用加密算法和秘钥将明文转变为密文的过程。

二、数据加密的方式

  1、单向加密

  指只能加密数据而不能解密数据,这种加密方式主要是为了保证数据的完整性,常见的加密算法有MD5、sha系列等(位于python内置的hashlib模块中)。

  2、对称加密

  指数据加密和解密使用相同的秘钥,这种加密方式主要是为了保证数据的机密性,常见的加密算法有DES、AES(位于python第三方库pycrytodomex中)。

  3、非对称加密

  也叫公钥加密,指数据加密和解密使用不同的密钥,这种加密方式基本不可能被破解,主要用于身份验证等方面,常见的加密算法有DSA、RSA(位于python第三方模块rsa中)。

三、加密算法

  1、单向加密算法(MD5、sha系列)

from hashlib import md5, sha256, sha512

m = md5()
m.update("123".encode())
print(m.hexdigest())  # 32
# 202cb962ac59075b964b07152d234b70
print(m.digest())
# b\' ,\\xb9b\\xacY\\x07[\\x96K\\x07\\x15-#Kp\'

s = sha512()
s.update("123".encode())
print(s.hexdigest())
# 3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2
print(s.digest())
b\'<\\x99\\t\\xaf\\xec%5MU\\x1d\\xae!Y\\x0b\\xb2n8\\xd5?!s\\xb8\\xd3\\xdc>\\xeeL\\x04~z\\xb1\\xc1\\xeb\\x8b\\x85\\x10>;\\xe7\\xbaa;1\\xbb\\\\\\x9c6!M\\xc9\\xf1JB\\xfdz/\\xdb\\x84\\x85k\\xca\\\\D\\xc2\'

  2、对称加密算法(AES、DES)

  安装第三方库:

    pip install pycryptodomex -i https://pypi.douban.com/simple

  DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准。 DES是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密用的是同一个算法。 DES算法的入口参数有三个:Key1。其中Key为8个字节共64位,是DES算法的工作密钥;Data为8个字节64位的整数倍,是要被加密或被解密的数据** 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1),对64位二进制数据块进行加密,分组后的明文组和56位的密钥按位替代或交换的方法形成密文组。每次加密对64位的输入数据进行16轮编码,经过一系列替换和移位后转换成完全不同的64位输出数据。

from Cryptodome.Cipher import DES

key = b\'88888888\'
data = "Good Good Study! Day Day Up!"
count = 8 - (len(data) % 8)
plaintext = data + count * "="
des = DES.new(key, DES.MODE_ECB)
ciphertext = des.encrypt(plaintext.encode())
print(ciphertext)
# b\'D\\xa4Z\\x1dt\\xba\\xf3\\xe8\\xdbv\\x1aP\\x81\\xe4\\xe6Jx?\\xfe\\xf2\\x0b\\x82\\nG\\x08d\\xea\\xd0\\t\\x07vs\'
plaintext = des.decrypt(ciphertext)
plaintext = plaintext[:(len(plaintext)-count)]
print(plaintext)
# b\'Good Good Study! Day Day Up!\'

  3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。 由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解。3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。 3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样: 3DES加密过程为:C=Ek3(Dk2(Ek1(M))) 3DES解密过程为:M=Dk1(EK2(Dk3(C)))。

  AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。

from Cryptodome.Cipher import DES, AES
from Cryptodome import Random

# 密钥的长度为16字节、24字节或32字节
key = b"8888888888888888"
print(AES.block_size)  # 16
iv = Random.new().read(AES.block_size)  # 也可以为24、32
plaintext = "测试数据"  # 该数据长度不受限制
aes = AES.new(key, AES.MODE_EAX, iv)
ciphertext = aes.encrypt(plaintext.encode())
# 一般后端会将iv放在加密的数据前一起传递到前端
transform_data = iv + ciphertext
print(transform_data)
# b\'\\x9e\\xabF\\xddx\\xfa\\x9f\\xb7\\x91\\xa0\\xafp\\xee\\xe9w\\x8e\\x11\\x08\\x12\\xae\\x0b\\xc0\\xc1\\xbe\\x80\\xb2\\xff\\x0c\'
iv = transform_data[:16]
aes = AES.new(key, AES.MODE_EAX, iv)
plaintext = aes.decrypt(transform_data[16:])
print(plaintext)
# b\'\\xe6\\xb5\\x8b\\xe8\\xaf\\x95\\xe6\\x95\\xb0\\xe6\\x8d\\xae\'
print(plaintext.decode())
# 测试数据

  3、非对称加密算法(RSA、DSA)

  安装第三方库:

    pip install rsa -i https://pypi.douban.com/simple

  指的是加密和解密使用不同的秘钥。 一把作为公开的公钥,另一把作为私钥。这对密钥中的公钥进行加密,私钥用于解密。反之亦然(被私钥加密的数据也可以被公钥解密) 。 在实际使用中私钥一般保存在发布者手中,是私有的不对外公开的,只将公钥对外公布,就能实现只有私钥的持有者才能将数据解密的方法。 这种加密方式安全系数很高,因为它不用将解密的密钥进行传递,从而没有密钥在传递过程中被截获的风险,而破解密文几乎又是不可能的。 但是算法的效率低,所以常用于很重要数据的加密,常和对称配合使用,使用非对称加密的密钥去加密对称加密的密钥。 事实上,**公钥加密算法很少用于数据加密,它通常只是用来做身份认证**,因为它的密钥太长,加密速度太慢--公钥加密算法的速度甚至比对称加密算法的速度慢上3个数量级(1000倍)。

import rsa
# 公钥加密、私钥解密
public_key, private_key = rsa.newkeys(1024)
print(public_key)
# PublicKey(115358647593237027749555219330290547595292720354379729059572469455025379115527291514465303947468690370446593609121177089794716265226101498361786298396410892325533861129676356325971818358112602498513419680609056457389715318966834362898086552554130435425753061655286667511557573410756120684188042377774434444807, 65537)
print(private_key)
# PrivateKey(115358647593237027749555219330290547595292720354379729059572469455025379115527291514465303947468690370446593609121177089794716265226101498361786298396410892325533861129676356325971818358112602498513419680609056457389715318966834362898086552554130435425753061655286667511557573410756120684188042377774434444807, 65537, 111285529956928522901721617280604228002764723117703733926382810265271061290888840676549733913221737511493431004615227720952917381576663793443813612330045581626681883557204892676718975967265771623672679503776812616315334112382868415864141371197836942710738341439472967902074841400226409659228441303650822610777, 
# 38470842708546405208704625508367712891471208299333441783981501073550023095274000403563916879641908231011170773153102126825952183163444780110955065002626432268349573, 2998599444966402616240989100234166167805477168671480027322013770416359562366030923233399853472241710845190991402502764232214027989568380839340059)
plaintext = b"15863274538"
ciphertext = rsa.encrypt(plaintext, public_key)
print(ciphertext)
# b\'\\x04\\xb3ri\\x1e\\nA\\xfb\\x94\\xff\\xde{HtNw\\xd4Q{\\xdeRJ\\xe0Fwl\\x97kL\\xde\\xe6m\\xc1\\x8f\\xd4\\t\\x96=\\xb62\\xad\\x02\\xfe\\xeb4\\xb4i\\x8f\\x9e\\x0fp\\x10\\xbe\\x8fiNrrUB\\xbc\\xe3\\x87Q-\\xe2\\xa5\\x86\\xd9\\x0b6,.\\x90\\xa1\\xa6\\x80\\xf3\\xaa\\xcc\\xdf7!\\xdcp\\xea\\x0eE_?$\\x8b\\xcd\\xb2\\xca\\x18\\xf9e\\xb5\\x9b^\\x84CcU\\xe5.\\xaeeFlz\\xdeh\\xb8\\xa3D\\xcb\\xb6\\xd5\\x02\\xe38\\x98\\xc80#Q\'
plaintext = rsa.decrypt(ciphertext, private_key)
print(plaintext)
# b\'15863274538\'


# 私钥加签、公钥验签
plaintext = b"15863274538"
sign_message = rsa.sign(plaintext, private_key, "MD5")
plaintext = b"15863274538"
method = rsa.verify(b"15863274532", sign_message, public_key)
print(method)
# rsa.pkcs1.VerificationError: Verification failed

  4、补充算法(base64) 

  目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一。在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输。那么,Base64到底起到什么作用呢? 在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现乱码情况。与此类似,网络上传输的字符并不全是可打印的字符,比如二进制文件、图片等。Base64的出现就是为了解决此问题,它是基于64个可打印的字符来表示二进制的数据的一种方法。 电子邮件刚问世的时候,只能传输英文,但后来随着用户的增加,中文、日文等文字的用户也有需求,但这些字符并不能被服务器或网关有效处理,因此Base64就登场了。随之,Base64在URL、Cookie、网页传输少量二进制文件中也有相应的使用。 原文链接:https://blog.csdn.net/wo541075754/article/details/81734770

from base64 import b64encode, b64decode

plaintext = "我的银行卡密码是020012"
ciphertext = b64encode(plaintext.encode())
print(ciphertext)
# b\'5oiR55qE6ZO26KGM5Y2h5a+G56CB5pivMDIwMDEy\'
plaintext = b64decode(ciphertext)
print(plaintext)
# b\'\\xe6\\x88\\x91\\xe7\\x9a\\x84\\xe9\\x93\\xb6\\xe8\\xa1\\x8c\\xe5\\x8d\\xa1\\xe5\\xaf\\x86\\xe7\\xa0\\x81\\xe6\\x98\\xaf020012\'
print(plaintext.decode())
# 我的银行卡密码是020012

 

 

 

以上是关于python爬虫之数据加密解密的主要内容,如果未能解决你的问题,请参考以下文章

Python3爬虫反反爬之搞定同程旅游加密参数 antitoken

scrapy按顺序启动多个爬虫代码片段(python3)

#yyds干货盘点# Python网络爬虫之js逆向之远程调用(rpc)免去抠代码补环境简介

# yyds干货盘点 # Python网络爬虫之js逆向之远程调用(rpc)免去抠代码补环境简介

scrapy主动退出爬虫的代码片段(python3)

python爬虫之新浪微博登录