潭州課堂25班:Ph201805201 爬蟲基礎 第七課 Python與常見加密方式 (課堂筆記)

打開圖形界面  18版

 

 

Python與常見加密方式


前言

咱們所說的加密方式,都是對二進制編碼的格式進行加密的,對應到Python中,則是咱們的Bytespython

因此當咱們在Python中進行加密操做的時候,要確保咱們操做的是Bytes,不然就會報錯。c++

將字符串和Bytes互相轉換可使用encode()decode()方法。以下所示:算法

# 方法中不傳參數則是以默認的utf-8編碼進行轉換 In [1]: '南北'.encode() Out[1]: b'\xe5\x8d\x97\xe5\x8c\x97' In [2]: b'\xe5\x8d\x97\xe5\x8c\x97'.decode() Out[2]: '南北' 

注:兩位十六進制經常用來顯示一個二進制字節。sql

利用binascii模塊能夠將十六進制顯示的字節轉換成咱們在加解密中更經常使用的顯示方式:shell

In [1]: import binascii In [2]: '南北'.encode() Out[2]: b'\xe5\x8d\x97\xe5\x8c\x97' In [3]: binascii.b2a_hex('南北'.encode()) Out[3]: b'e58d97e58c97' In [4]: binascii.a2b_hex(b'e58d97e58c97') Out[4]: b'\xe5\x8d\x97\xe5\x8c\x97' In [5]: binascii.a2b_hex(b'e58d97e58c97').decode() Out[5]: '南北' 

URL編碼

簡介

正常的URL中是隻能包含ASCII字符的,也就是字符、數字和一些符號。而URL編碼就是一種瀏覽器用來避免url中出現特殊字符(如漢字)的編碼方式。數組

其實就是將超出ASCII範圍的字符轉換成帶%的十六進制格式。瀏覽器

Python實現

In [1]: from urllib import parse # quote()方法會自動將str轉換成bytes,因此這裏傳入str和bytes均可以 In [2]: parse.quote('南北') Out[2]: '%E5%8D%97%E5%8C%97' In [3]: parse.unquote('%E5%8D%97%E5%8C%97') Out[3]: '南北' 

Base64編碼

簡述

Base64是一種用64個字符來表示任意二進制數據的方法。安全

Base64編碼能夠成爲密碼學的基石。能夠將任意的二進制數據進行Base64編碼。全部的數據都能被編碼爲並只用65個字符就能表示的文本文件。( 65字符:A~Z a~z 0~9 + / = )編碼後的數據~=編碼前數據的4/3,會大1/3左右。dom

Base64編碼的原理

 

1524836141496

1524836141496

 

  1. 將全部字符轉化爲ASCII碼。ide

  2. 將ASCII碼轉化爲8位二進制 。

  3. 將二進制3個歸成一組(不足3個在後邊補0)共24位,再拆分紅4組,每組6位。

  4. 統一在6位二進制前補兩個0湊足8位。

  5. 將補0後的二進制轉爲十進制。

  6. 從Base64編碼表獲取十進制對應的Base64編碼。

Base64編碼的說明

  1. 轉換的時候,將三個byte的數據,前後放入一個24bit的緩衝區中,先來的byte佔高位。

  2. 數據不足3byte的話,於緩衝區中剩下的bit用0補足。而後,每次取出6個bit,按照其值選擇查表選擇對應的字符做爲編碼後的輸出。

  3. 不斷進行,直到所有輸入數據轉換完成。

  4. 若是最後剩下兩個輸入數據,在編碼結果後加1個「=」。

  5. 若是最後剩下一個輸入數據,編碼結果後加2個「=」。

  6. 若是沒有剩下任何數據,就什麼都不要加,這樣才能夠保證資料還原的正確性。

Python的Base64使用

Python內置的base64模塊能夠直接進行base64的編解碼

注意:用於base64編碼的,要麼是ASCII包含的字符,要麼是二進制數據

In [1]: import base64 In [2]: base64.b64encode(b'hello world') Out[2]: b'aGVsbG8gd29ybGQ=' In [3]: base64.b64decode(b'aGVsbG8gd29ybGQ=') Out[3]: b'hello world' 

MD5(信息-摘要算法)

簡述

1比特(bit)=0.125字節(b)

1B就是1個字節。

Byte、KB、B、MB、GB之間的關係是:
Bit——比特
B ——字節
KB——千字節
MB——兆字節
GB——吉字節
TB——太字節

1B=8 Bit
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB

message-digest algorithm 5(信息-摘要算法)。常常說的「MD5加密」,就是它→信息-摘要算法。

md5,其實就是一種算法。能夠將一個字符串,或文件,或壓縮包,執行md5後,就能夠生成一個固定長度爲128bit的串。這個串,基本上是惟一的。

不可逆性

每一個人都有不一樣的指紋,看到這我的,能夠得出他的指紋等信息,而且惟一對應,但你只看一個指紋,是不可能看到或讀到這我的的長相或身份等信息。

特色

  1. 壓縮性:任意長度的數據,算出的MD5值長度都是固定的。

  2. 容易計算:從原數據計算出MD5值很容易。

  3. 抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所獲得的MD5值都有很大區別。

  4. 強抗碰撞:已知原數據和其MD5值,想找到一個具備相同MD5值的數據(即僞造數據)是很是困難的。

舉個栗子:世界上只有一個我,可是可是妞倒是很是很是多的,以一個有限的我對幾乎是無限的妞,因此可能能搞定很是多(100+)的妞,這個理論上的確是通的,但是實際狀況下....

Python的MD5使用

因爲MD5模塊在python3中被移除,在python3中使用hashlib模塊進行md5操做

import hashlib # 待加密信息 str = '這是一個測試' # 建立md5對象 hl = hashlib.md5() # 此處必須聲明encode # 若寫法爲hl.update(str) 報錯爲: Unicode-objects must be encoded before hashing hl.update(str.encode(encoding='utf-8')) print('MD5加密前爲 :' + str) print('MD5加密後爲 :' + hl.hexdigest()) 

運行結果

MD5加密前爲 :這是一個測試
MD5加密後爲 :cfca700b9e09cf664f3ae80733274d9f

MD5長度

md5的長度,默認爲128bit--》32字節,也就是128個0和1的二進制串。這樣表達是很不友好的。因此將二進制轉成了16進制,每4個bit表示一個16進制,因此128/4 = 32 換成16進製表示後,爲32位了。

爲何網上還有md5是16位的呢?

其實16位的長度,是從32位md5值來的。是將32位md5去掉前八位,去掉後八位獲得的。


Python加密庫PyCryptodome

PyCrypto是 Python 中密碼學方面最有名的第三方軟件包。惋惜的是,它的開發工做於2012年就已中止。

幸運的是,有一個該項目的分支PyCrytodome 取代了 PyCrypto 。

安裝與導入

Windows安裝以前須要先安裝Microsoft Visual c++ 2015

在Linux上安裝,可使用如下 pip 命令:

pip install pycryptodome 

導入:

import Crypto 

在Windows 系統上安裝則稍有不一樣:

pip install pycryptodomex 

導入:

import Cryptodome 

DES

簡介

DES算法爲密碼體制中的對稱密碼體制,又被稱爲美國數據加密標準。

DES是一個分組加密算法,典型的DES以64位爲分組對數據加密,加密和解密用的是同一個算法。

DES算法的入口參數有三個:Key、Data、Mode。其中Key爲7個字節共56位,是DES算法的工做密鑰;Data爲8個字節64位,是要被加密或被解密的數據;Mode爲DES的工做方式,有兩種:加密或解密。

密鑰長64位,密鑰事實上是56位參與DES運算(第八、1六、2四、3二、40、4八、5六、64位是校驗位,使得每一個密鑰都有奇數個1),分組後的明文組和56位的密鑰按位替代或交換的方法造成密文組。

例子

# 導入DES模塊 from Cryptodome.Cipher import DES import binascii # 這是密鑰 key = b'abcdefgh' # 必須八位 # 須要去生成一個DES對象 des = DES.new(key, DES.MODE_ECB) # 須要加密的數據 text = 'python spider!' # 必須爲8的倍數 text = text + (8 - (len(text) % 8)) * '=' # 加密的過程 encrypto_text = des.encrypt(text.encode()) encrypto_text = binascii.b2a_hex(encrypto_text) print(encrypto_text) # 解密(咱們通常不用擔憂解密) encrypto_text = des.decrypt(encrypto_text) print(encrypto_text) 

3DES(過渡算法 過渡到AES 不詳講)

簡介

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

簡介

高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。通過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日發佈於FIPS PUB 197,並在2002年5月26日成爲有效的標準。2006年,高級加密標準已然成爲對稱密鑰加密中最流行的算法之一。

AES在軟件及硬件上都能快速地加解密,相對來講較易於實做,且只須要不多的存儲器。做爲一個新的加密標準,目前正被部署應用到更廣大的範圍。

特色與思想

  1. 抵抗全部已知的攻擊。

  2. 在多個平臺上速度快,編碼緊湊。

  3. 設計簡單。

詳解

 

1524901614191

1524901614191

 

AES爲分組密碼,分組密碼也就是把明文分紅一組一組的,每組長度相等,每次加密一組數據,直到加密完整個明文。在AES標準規範中,分組長度只能是128位,也就是說,每一個分組爲16個字節(每一個字節8位)。密鑰的長度可使用128位、192位或256位。密鑰的長度不一樣,推薦加密輪數也不一樣。

通常經常使用的是128位

###Python實現

from Cryptodome.Cipher import AES from Cryptodome import Random from binascii import b2a_hex # 要加密的明文 data = '南來北往' # 也必需要是8的倍數 可是AES自動補全 # 密鑰key 長度必須爲16(AES-128)、24(AES-192)、或32(AES-256)Bytes 長度. # 目前AES-128足夠用 key = b'this is a 16 key' # 生成長度等於AES塊大小的不可重複的密鑰向量 iv = Random.new().read(AES.block_size) # 使用key和iv初始化AES對象, 使用MODE_CFB模式 mycipher = AES.new(key, AES.MODE_CFB, iv) # 加密的明文長度必須爲16的倍數,若是長度不爲16的倍數,則須要補足爲16的倍數 # 將iv(密鑰向量)加到加密的密文開頭,一塊兒傳輸 ciphertext = iv + mycipher.encrypt(data.encode()) # 解密的話要用key和iv生成新的AES對象 mydecrypt = AES.new(key, AES.MODE_CFB, ciphertext[:16]) # 使用新生成的AES對象,將加密的密文解密 decrypttext = mydecrypt.decrypt(ciphertext[16:]) print('密鑰k爲:', key) print('iv爲:', b2a_hex(ciphertext)[:16]) print('加密後數據爲:', b2a_hex(ciphertext)[16:]) print('解密後數據爲:', decrypttext.decode()) 

運行結果:

密鑰k爲: b'this is a 16 key' iv爲: b'a78a177cffd50878' 加密後數據爲: b'33f61e7678c25d795d565d40f2f68371da051202' 解密後數據爲: 南來北往 

RSA

非對稱加密

典型的如RSA等,常見方法,使用openssl ,keytools等工具生成一對公私鑰對,使用被公鑰加密的數據可使用私鑰來解密,反之亦然(被私鑰加密的數據也能夠被公鑰解密) 。

在實際使用中私鑰通常保存在發佈者手中,是私有的不對外公開的,只將公鑰對外公佈,就能實現只有私鑰的持有者才能將數據解密的方法。 這種加密方式安全係數很高,由於它不用將解密的密鑰進行傳遞,從而沒有密鑰在傳遞過程當中被截獲的風險,而破解密文幾乎又是不可能的。

可是算法的效率低,因此經常使用於很重要數據的加密,常和對稱配合使用,使用非對稱加密的密鑰去加密對稱加密的密鑰。

簡介

RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業中RSA被普遍使用。

該算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,所以能夠將乘積公開做爲加密密鑰,即公鑰,而兩個大素數組合成私鑰。公鑰是可發佈的供任何人使用,私鑰則爲本身全部,供解密之用。

Python實現

首先咱們須要安裝一個rsa模塊:

pip install rsa 

並且,由於RSA加密算法的特性,RSA的公鑰私鑰都是10進制的,但公鑰的值經常保存爲16進制的格式,因此須要將其用int()方法轉換爲10進制格式。

用網頁中的公鑰把數據加密

import rsa import binascii # 使用網頁中得到的n和e值,將明文加密 def rsa_encrypt(rsa_n, rsa_e, message): # 用n值和e值生成公鑰 key = rsa.PublicKey(rsa_n, rsa_e) # 用公鑰把明文加密 message = rsa.encrypt(message.encode(), key) # 轉化成經常使用的可讀性高的十六進制 message = binascii.b2a_hex(message) # 將加密結果轉化回字符串並返回 return message.decode() # RSA的公鑰有兩個值n和e,咱們在網站中得到的公鑰通常就是這樣的兩個值。 # n經常爲長度爲256的十六進制字符串 # e經常爲十六進制‘10001’ pubkey_n = '8d7e6949d411ce14d7d233d7160f5b2cc753930caba4d5ad24f923a505253b9c39b09a059732250e56c594d735077cfcb0c3508e9f544f101bdf7e97fe1b0d97f273468264b8b24caaa2a90cd9708a417c51cf8ba35444d37c514a0490441a773ccb121034f29748763c6c4f76eb0303559c57071fd89234d140c8bb965f9725' pubkey_e = '10001' # 須要將十六進制轉換成十進制 rsa_n = int(pubkey_n, 16) rsa_e = int(pubkey_e, 16) # 要加密的明文 message = '南北今天很忙' print("公鑰n值長度:", len(pubkey_n)) print(rsa_encrypt(rsa_n, rsa_e, message)) 

運行結果:

公鑰n值長度: 256 480f302eed822c8250256511ddeb017fcb28949cc05739ae66440eecc4ab76e7a7b2f1df398aefdfef2b9bfce6d6152bf6cc1552a0ed8bebee9e094a7ce9a52622487a6412632144787aa81f6ec9b96be95890c4c28a31b3e8d9ea430080d79297c5d75cd11df04df6e71b237511164399d72ccb2f4c34022b1ea7b76189a56e 

做業

將AES和RSA的加密過程經過面向對象的方式寫成一個類,封裝起來。

只須要傳入一些參數就能夠進行加密。



相關文章
相關標籤/搜索