日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

常見(jiàn)加密方式和Python實(shí)現(xiàn)

系統(tǒng) 1825 0
原文鏈接: https://www.jianshu.com/p/4ba20afacce2

1. 前言

我們所說(shuō)的加密方式,都是對(duì)二進(jìn)制編碼的格式進(jìn)行加密的,對(duì)應(yīng)到Python中,則是我們的 Bytes

所以當(dāng)我們?cè)赑ython中進(jìn)行加密操作的時(shí)候,要確保我們操作的是 Bytes ,否則就會(huì)報(bào)錯(cuò)。

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

            
              # 方法中不傳參數(shù)則是以默認(rèn)的utf-8編碼進(jìn)行轉(zhuǎn)換
In [1]: '南北'.encode()
Out[1]: b'\xe5\x8d\x97\xe5\x8c\x97'

In [2]: b'\xe5\x8d\x97\xe5\x8c\x97'.decode()
Out[2]: '南北'

            
          

注:兩位十六進(jìn)制常常用來(lái)顯示一個(gè)二進(jìn)制字節(jié)。

利用 binascii 模塊可以將十六進(jìn)制顯示的字節(jié)轉(zhuǎn)換成我們?cè)诩咏饷苤懈S玫娘@示方式:

            
              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]: '南北'

            
          

2. URL編碼

正常的URL中是只能包含ASCII字符的,也就是字符、數(shù)字和一些符號(hào)。而URL編碼就是一種瀏覽器用來(lái)避免url中出現(xiàn)特殊字符(如漢字)的編碼方式。

其實(shí)就是將超出ASCII范圍的字符轉(zhuǎn)換成帶 % 的十六進(jìn)制格式。

例子

            
              In [1]: from urllib import parse

# quote()方法會(huì)自動(dòng)將str轉(zhuǎn)換成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]: '南北'

            
          

3. Base64編碼

Base64是一種用64個(gè)字符來(lái)表示任意二進(jìn)制數(shù)據(jù)的方法。

Base64編碼可以稱(chēng)為密碼學(xué)的基石。可以將任意的二進(jìn)制數(shù)據(jù)進(jìn)行Base64編碼。所有的數(shù)據(jù)都能被編碼為并只用65個(gè)字符就能表示的文本文件。( 65字符:A~Z a~z 0~9 + / = )編碼后的數(shù)據(jù)~=編碼前數(shù)據(jù)的4/3,會(huì)大1/3左右。

3.1. 原理

常見(jiàn)加密方式和Python實(shí)現(xiàn)_第1張圖片

image.png

  1. 將所有字符轉(zhuǎn)化為ASCII碼。
  2. 將ASCII碼轉(zhuǎn)化為8位二進(jìn)制 。
  3. 將二進(jìn)制3個(gè)歸成一組(不足3個(gè)在后邊補(bǔ)0)共24位,再拆分成4組,每組6位。
  4. 統(tǒng)一在6位二進(jìn)制前補(bǔ)兩個(gè)0湊足8位。
  5. 將補(bǔ)0后的二進(jìn)制轉(zhuǎn)為十進(jìn)制。
  6. 從Base64編碼表獲取十進(jìn)制對(duì)應(yīng)的Base64編碼。

3.2. 說(shuō)明

  1. 轉(zhuǎn)換的時(shí)候,將三個(gè)byte的數(shù)據(jù),先后放入一個(gè)24bit的緩沖區(qū)中,先來(lái)的byte占高位。
  2. 數(shù)據(jù)不足3byte的話(huà),于緩沖區(qū)中剩下的bit用0補(bǔ)足。然后,每次取出6個(gè)bit,按照其值選擇查表選擇對(duì)應(yīng)的字符作為編碼后的輸出。
  3. 不斷進(jìn)行,直到全部輸入數(shù)據(jù)轉(zhuǎn)換完成。
  4. 如果最后剩下兩個(gè)輸入數(shù)據(jù),在編碼結(jié)果后加1個(gè)“=”。
  5. 如果最后剩下一個(gè)輸入數(shù)據(jù),編碼結(jié)果后加2個(gè)“=”。
  6. 如果沒(méi)有剩下任何數(shù)據(jù),就什么都不要加,這樣才可以保證資料還原的正確性。

3.3. python使用

Python內(nèi)置的 base64 模塊可以直接進(jìn)行base64的編解碼

注意:用于base64編碼的,要么是ASCII包含的字符,要么是二進(jìn)制數(shù)據(jù)

            
              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'

            
          

4. MD5(信息-摘要算法)

message-digest algorithm 5(信息-摘要算法)。經(jīng)常說(shuō)的“MD5加密”,就是信息摘要算法。

md5,其實(shí)就是一種算法。可以將一個(gè)字符串,或文件,或壓縮包,執(zhí)行md5后,就可以生成一個(gè)固定長(zhǎng)度為128bit的串。這個(gè)串,基本上是唯一的。

4.1. 特點(diǎn)

  1. 壓縮性:任意長(zhǎng)度的數(shù)據(jù),算出的MD5值長(zhǎng)度都是固定的。
  2. 容易計(jì)算:從原數(shù)據(jù)計(jì)算出MD5值很容易。
  3. 抗修改性:對(duì)原數(shù)據(jù)進(jìn)行任何改動(dòng),哪怕只修改1個(gè)字節(jié),所得到的MD5值都有很大區(qū)別。
  4. 強(qiáng)抗碰撞:已知原數(shù)據(jù)和其MD5值,想找到一個(gè)具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的。
  5. 不可逆性:每個(gè)人都有不同的指紋,看到這個(gè)人,可以得出他的指紋等信息,并且唯一對(duì)應(yīng),但你只看一個(gè)指紋,是不可能看到或讀到這個(gè)人的長(zhǎng)相或身份等信息。

舉個(gè)栗子:世界上只有一個(gè)我,但是但是妞卻是非常非常多的,以一個(gè)有限的我對(duì)幾乎是無(wú)限的妞,所以可能能搞定非常多(100+)的妞,這個(gè)理論上的確是通的,可是實(shí)際情況下....

4.2. python使用

由于MD5模塊在python3中被移除,在python3中使用 hashlib 模塊進(jìn)行md5操作

            
              import hashlib

# 待加密信息
str = '這是一個(gè)測(cè)試'

# 創(chuàng)建md5對(duì)象
hl = hashlib.md5()

# 此處必須聲明encode
# 若寫(xiě)法為hl.update(str)  報(bào)錯(cuò)為: Unicode-objects must be encoded before hashing
hl.update(str.encode(encoding='utf-8'))

print('MD5加密前為 :' + str)
print('MD5加密后為 :' + hl.hexdigest())

            
          

運(yùn)行結(jié)果

            
              MD5加密前為 :這是一個(gè)測(cè)試
MD5加密后為 :cfca700b9e09cf664f3ae80733274d9f

            
          

md5的長(zhǎng)度,默認(rèn)為128bit,也就是128個(gè)0和1的二進(jìn)制串。這樣表達(dá)是很不友好的。所以將二進(jìn)制轉(zhuǎn)成了16進(jìn)制,每4個(gè)bit表示一個(gè)16進(jìn)制,所以128/4 = 32 換成16進(jìn)制表示后,為32位了。

為什么網(wǎng)上還有md5是16位的呢?

其實(shí)16位的長(zhǎng)度,是從32位md5值來(lái)的。是將32位md5去掉前八位,去掉后八位得到的。


5. Python加密庫(kù)PyCryptodome

PyCrypto是 Python 中密碼學(xué)方面最有名的第三方軟件包,提供了許多加密算法的使用。可惜的是,它的開(kāi)發(fā)工作于2012年就已停止。

幸運(yùn)的是,有一個(gè)該項(xiàng)目的分支PyCrytodome 取代了 PyCrypto 。

5.1. 安裝與導(dǎo)入

安裝之前需要先安裝 Microsoft Visual c++ 2015

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

            
              pip install pycryptodome

            
          

導(dǎo)入:

            
              import Crypto

            
          

在Windows 系統(tǒng)上安裝則稍有不同:

            
              pip install pycryptodomex

            
          

導(dǎo)入:

            
              import Cryptodome

            
          

6. DES

DES算法為密碼體制中的對(duì)稱(chēng)密碼體制,又被稱(chēng)為美國(guó)數(shù)據(jù)加密標(biāo)準(zhǔn)。

DES是一個(gè)分組加密算法,典型的DES以64位為分組對(duì)數(shù)據(jù)加密,加密和解密用的是同一個(gè)算法。

DES算法的入口參數(shù)有三個(gè):Key、Data、Mode。其中Key為7個(gè)字節(jié)共56位,是DES算法的工作密鑰;Data為8個(gè)字節(jié)64位,是要被加密或被解密的數(shù)據(jù);Mode為DES的工作方式,有兩種:加密或解密。

密鑰長(zhǎng)64位,密鑰事實(shí)上是56位參與DES運(yùn)算(第8、16、24、32、40、48、56、64位是校驗(yàn)位,使得每個(gè)密鑰都有奇數(shù)個(gè)1),分組后的明文組和56位的密鑰按位替代或交換的方法形成密文組。

6.1. python使用

            
              # 導(dǎo)入DES模塊
from Cryptodome.Cipher import DES
import binascii

# 這是密鑰
key = b'abcdefgh'
# 需要去生成一個(gè)DES對(duì)象
des = DES.new(key, DES.MODE_ECB)
# 需要加密的數(shù)據(jù)
text = 'python spider!'
text = text + (8 - (len(text) % 8)) * '='

# 加密的過(guò)程
encrypto_text = des.encrypt(text.encode())
encrypto_text = binascii.b2a_hex(encrypto_text)
print(encrypto_text)

            
          

7. 3DES

3DES(或稱(chēng)為T(mén)riple DES)是三重?cái)?shù)據(jù)加密算法(TDEA,Triple Data Encryption Algorithm)塊密碼的通稱(chēng)。它相當(dāng)于是對(duì)每個(gè)數(shù)據(jù)塊應(yīng)用三次DES加密算法。

由于計(jì)算機(jī)運(yùn)算能力的增強(qiáng),原版DES密碼的密鑰長(zhǎng)度變得容易被暴力破解。3DES即是設(shè)計(jì)用來(lái)提供一種相對(duì)簡(jiǎn)單的方法,即通過(guò)增加DES的密鑰長(zhǎng)度來(lái)避免類(lèi)似的攻擊,而不是設(shè)計(jì)一種全新的塊密碼算法。

3DES(即Triple DES)是DES向AES過(guò)渡的加密算法(1999年,NIST將3-DES指定為過(guò)渡的加密標(biāo)準(zhǔn)),加密算法,其具體實(shí)現(xiàn)如下:設(shè)Ek()和Dk()代表DES算法的加密和解密過(guò)程,K代表DES算法使用的密鑰,M代表明文,C代表密文,這樣:

3DES加密過(guò)程為:C=Ek3(Dk2(Ek1(M)))

3DES解密過(guò)程為:M=Dk1(EK2(Dk3(C)))


8. AES

高級(jí)加密標(biāo)準(zhǔn) (英語(yǔ): Advanced Encryption Standard ,縮寫(xiě): AES ),在密碼學(xué)中又稱(chēng) Rijndael加密法 ,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用。經(jīng)過(guò)五年的甄選流程,高級(jí)加密標(biāo)準(zhǔn)由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)于2001年11月26日發(fā)布于FIPS PUB 197,并在2002年5月26日成為有效的標(biāo)準(zhǔn)。2006年,高級(jí)加密標(biāo)準(zhǔn)已然成為對(duì)稱(chēng)密鑰加密中最流行的算法之一。

AES在軟件及硬件上都能快速地加解密,相對(duì)來(lái)說(shuō)較易于實(shí)作,且只需要很少的存儲(chǔ)器。作為一個(gè)新的加密標(biāo)準(zhǔn),目前正被部署應(yīng)用到更廣大的范圍。

8.1. 特點(diǎn)

  1. 抵抗所有已知的攻擊。
  2. 在多個(gè)平臺(tái)上速度快,編碼緊湊。
  3. 設(shè)計(jì)簡(jiǎn)單。

常見(jiàn)加密方式和Python實(shí)現(xiàn)_第2張圖片

image.png

AES為分組密碼,分組密碼也就是把明文分成一組一組的,每組長(zhǎng)度相等,每次加密一組數(shù)據(jù),直到加密完整個(gè)明文。在AES標(biāo)準(zhǔn)規(guī)范中,分組長(zhǎng)度只能是128位,也就是說(shuō),每個(gè)分組為16個(gè)字節(jié)(每個(gè)字節(jié)8位)。密鑰的長(zhǎng)度可以使用128位、192位或256位。密鑰的長(zhǎng)度不同,推薦加密輪數(shù)也不同。

一般常用的是128位

8.2. Python實(shí)現(xiàn)

            
              from Cryptodome.Cipher import AES
from Cryptodome import Random
from binascii import b2a_hex  

# 要加密的明文
data = '南來(lái)北往'
# 密鑰key 長(zhǎng)度必須為16(AES-128)、24(AES-192)、或32(AES-256)Bytes 長(zhǎng)度.
# 目前AES-128足夠用
key = b'this is a 16 key'
# 生成長(zhǎng)度等于AES塊大小的不可重復(fù)的密鑰向量
iv = Random.new().read(AES.block_size)

# 使用key和iv初始化AES對(duì)象, 使用MODE_CFB模式
mycipher = AES.new(key, AES.MODE_CFB, iv)
# 加密的明文長(zhǎng)度必須為16的倍數(shù),如果長(zhǎng)度不為16的倍數(shù),則需要補(bǔ)足為16的倍數(shù)
# 將iv(密鑰向量)加到加密的密文開(kāi)頭,一起傳輸
ciphertext = iv + mycipher.encrypt(data.encode())

# 解密的話(huà)要用key和iv生成新的AES對(duì)象
mydecrypt = AES.new(key, AES.MODE_CFB, ciphertext[:16])
# 使用新生成的AES對(duì)象,將加密的密文解密
decrypttext = mydecrypt.decrypt(ciphertext[16:])


print('密鑰k為:', key)
print('iv為:', b2a_hex(ciphertext)[:16])
print('加密后數(shù)據(jù)為:', b2a_hex(ciphertext)[16:])
print('解密后數(shù)據(jù)為:', decrypttext.decode())


            
          

運(yùn)行結(jié)果:

            
              密鑰k為: b'this is a 16 key'
iv為: b'a78a177cffd50878'
加密后數(shù)據(jù)為: b'33f61e7678c25d795d565d40f2f68371da051202'
解密后數(shù)據(jù)為: 南來(lái)北往

            
          

9. RSA

RSA加密算法 是一種 非對(duì)稱(chēng)加密算法 。在公開(kāi)密鑰加密和電子商業(yè)中RSA被廣泛使用。

該算法基于一個(gè)十分簡(jiǎn)單的數(shù)論事實(shí):將兩個(gè)大素?cái)?shù)相乘十分容易,但那時(shí)想要對(duì)其乘積進(jìn)行因式分解卻極其困難,因此可以將乘積公開(kāi)作為加密密鑰,即公鑰,而兩個(gè)大素?cái)?shù)組合成私鑰。公鑰是可發(fā)布的供任何人使用,私鑰則為自己所有,供解密之用。

9.1. 非對(duì)稱(chēng)加密

典型的如RSA等,常見(jiàn)方法,使用openssl ,keytools等工具生成一對(duì)公私鑰對(duì),使用被公鑰加密的數(shù)據(jù)可以使用私鑰來(lái)解密,反之亦然(被私鑰加密的數(shù)據(jù)也可以被公鑰解密) 。

在實(shí)際使用中私鑰一般保存在發(fā)布者手中,是私有的不對(duì)外公開(kāi)的,只將公鑰對(duì)外公布,就能實(shí)現(xiàn)只有私鑰的持有者才能將數(shù)據(jù)解密的方法。 這種加密方式安全系數(shù)很高,因?yàn)樗挥脤⒔饷艿拿荑€進(jìn)行傳遞,從而沒(méi)有密鑰在傳遞過(guò)程中被截獲的風(fēng)險(xiǎn),而破解密文幾乎又是不可能的。

但是算法的效率低,所以常用于很重要數(shù)據(jù)的加密,常和對(duì)稱(chēng)配合使用,使用非對(duì)稱(chēng)加密的密鑰去加密對(duì)稱(chēng)加密的密鑰。

9.2. Python實(shí)現(xiàn)

首先我們需要安裝一個(gè) rsa 模塊:

            
              pip install rsa

            
          

而且,因?yàn)镽SA加密算法的特性,RSA的公鑰私鑰都是10進(jìn)制的,但公鑰的值常常保存為16進(jìn)制的格式,所以需要將其用 int() 方法轉(zhuǎn)換為10進(jìn)制格式。

            
              import rsa
import binascii

# 使用網(wǎng)頁(yè)中獲得的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)
    # 轉(zhuǎn)化成常用的可讀性高的十六進(jìn)制
    message = binascii.b2a_hex(message)
    # 將加密結(jié)果轉(zhuǎn)化回字符串并返回
    return message.decode()

# RSA的公鑰有兩個(gè)值n和e,我們?cè)诰W(wǎng)站中獲得的公鑰一般就是這樣的兩個(gè)值。
# n常常為長(zhǎng)度為256的十六進(jìn)制字符串
# e常常為十六進(jìn)制‘10001’
pubkey_n = '8d7e6949d411ce14d7d233d7160f5b2cc753930caba4d5ad24f923a505253b9c39b09a059732250e56c594d735077cfcb0c3508e9f544f101bdf7e97fe1b0d97f273468264b8b24caaa2a90cd9708a417c51cf8ba35444d37c514a0490441a773ccb121034f29748763c6c4f76eb0303559c57071fd89234d140c8bb965f9725'
pubkey_e = '10001'
# 需要將十六進(jìn)制轉(zhuǎn)換成十進(jìn)制
rsa_n = int(pubkey_n, 16)
rsa_e = int(pubkey_e, 16)
# 要加密的明文
message = '南北今天很忙'

print("公鑰n值長(zhǎng)度:", len(pubkey_n))
print(rsa_encrypt(rsa_n, rsa_e, message))

            
          

運(yùn)行結(jié)果:

            
              公鑰n值長(zhǎng)度: 256
480f302eed822c8250256511ddeb017fcb28949cc05739ae66440eecc4ab76e7a7b2f1df398aefdfef2b9bfce6
            
          



作者:王南北丶
鏈接:https://www.jianshu.com/p/4ba20afacce2
來(lái)源:簡(jiǎn)書(shū)
簡(jiǎn)書(shū)著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 平昌县| 宜兴市| 大城县| 元江| 瑞昌市| 上林县| 衡阳县| 阳西县| 平江县| 广平县| 皮山县| 乐安县| 屏东市| 勐海县| 逊克县| 织金县| 阿拉善左旗| 钦州市| 东乌| 左权县| 从化市| 珲春市| 柘荣县| 应用必备| 大化| 吐鲁番市| 寿宁县| 婺源县| 滦南县| 江孜县| 无极县| 且末县| 天水市| 南充市| 长岭县| 时尚| 卢湾区| 唐山市| 晋江市| 宾阳县| 柳林县|