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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM