在python實現加密的方式總結

来源:https://www.cnblogs.com/xxpythonxx/archive/2020/01/18/12210391.html
-Advertisement-
Play Games

基礎知識掃盲 對稱加密 對稱密鑰加密 , 又叫私鑰加密。即信息發送的方和接受方用一個密鑰去加密和揭秘數據。 最大的優勢是 加解密速度快,適合對大量數據進行加密, 對稱加密的缺點是密鑰的管理和分配, 換句話說就是 如何把密鑰發送到需要解密你的消息的人手裡的問題。在發送密鑰的過程中, 密鑰有很大的風險被 ...


基礎知識掃盲

對稱加密

對稱密鑰加密 , 又叫私鑰加密。即信息發送的方和接受方用一個密鑰去加密和揭秘數據。 最大的優勢是 加解密速度快,適合對大量數據進行加密, 對稱加密的缺點是密鑰的管理和分配, 換句話說就是 如何把密鑰發送到需要解密你的消息的人手裡的問題。在發送密鑰的過程中, 密鑰有很大的風險被黑客攔截。 現實中的做法是將對稱加密的密鑰進行非對稱加密然後傳給需要他的人。

非對稱加密

非對稱加密系統, 又稱公鑰密鑰加密。 非對稱加密為數據的加密與解密提供了一種非常安全的方式。她使用了一對密鑰, 私鑰和公鑰。 私鑰只能有一方安全保管, 不能外泄, 而公鑰可以發給任何請求她的人。非對稱加密使用這對密鑰中的一個進行加密, 而解密卻需要一個另外一個密鑰。 比如你去銀行 你向銀行請求公鑰,銀行將公鑰發給你,你使用公鑰對消息加密,那麼只有私鑰的持有人–銀行才能對你的消息解密。 與對稱加密的不同之處是, 銀行不需要將私鑰通過網路發送出去。因此安全性大大提高。 目前最常用的非對稱加密演算法是RSA演算法。公鑰機制靈活,但加密和解密速度卻比對稱密鑰加密慢得多。 公鑰機制靈活, 但是加密和解密速度卻要比堆成加密慢很多。

1) Alice需要在銀行的網站做一筆交易,她的瀏覽器首先生成了一個隨機數作為對稱密鑰。
(2) Alice的瀏覽器向銀行的網站請求公鑰。
(3) 銀行將公鑰發送給Alice。
(4) Alice的瀏覽器使用銀行的公鑰將自己的對稱密鑰加密。
(5) Alice的瀏覽器將加密後的對稱密鑰發送給銀行。
(6) 銀行使用私鑰解密得到Alice瀏覽器的對稱密鑰。
(7) Alice與銀行可以使用對稱密鑰來對溝通的內容進行加密與解密了。

總結
(1) 對稱加密加密與解密使用的是同樣的密鑰,所以速度快,但由於需要將密鑰在網路傳輸,所以安全性不高。
(2) 非對稱加密使用了一對密鑰,公鑰與私鑰,所以安全性高,但加密與解密速度慢。
(3) 解決的辦法是將對稱加密的密鑰使用非對稱加密的公鑰進行加密,然後發送出去,接收方使用私鑰進行解密得到對稱加密的密鑰,然後雙方可以使用對稱加密來進行溝通。

python中加密的註意點

我們所說的加密方式,都是對二進位編碼的格式進行加密的,對應到Python中,則是我們的Bytes。

所以當我們在Python中進行加密操作的時候,要確保我們操作的是Bytes,否則就會報錯。

將字元串和Bytes互相轉換可以使用encode()和decode()方法。

Base64

Base64是一種用64個字元來表示任意二進位數據的方法。

Base64編碼可以稱為密碼學的基石。可以將任意的二進位數據進行Base64編碼。所有的數據都能被編碼為並只用65個字元就能表示的文本文件。( 65字元:A~Z a~z 0~9 + / = )編碼後的數據~=編碼前數據的4/3,會大1/3左右。

原理

1.將所有字元轉化為ASCII碼。
2.將ASCII碼轉化為8位二進位 。
3.將二進位3個歸成一組(不足3個在後邊補0)共24位,再拆分成4組,每組6位。
4.統一在6位二進位前補兩個0湊足8位。
5.將補0後的二進位轉為十進位。
6.從Base64編碼表獲取十進位對應的Base64編碼。

說明

  1. 轉換的時候,將三個byte的數據,先後放入一個24bit的緩衝區中,先來的byte占高位。
  2. 數據不足3byte的話,於緩衝區中剩下的bit用0補足。然後,每次取出6個bit,按照其值選擇查表選擇對應的字元作為編碼後的輸出。
  3. 不斷進行,直到全部輸入數據轉換完成。
  4. 如果最後剩下兩個輸入數據,在編碼結果後加1個“=”。
  5. 如果最後剩下一個輸入數據,編碼結果後加2個“=”。
  6. 如果沒有剩下任何數據,就什麼都不要加,這樣才可以保證資料還原的正確性。

Base64加密與解密

註意:
1.用於base64編碼的,要麼是ASCII包含的字元,要麼是二進位數據
2.base64 是對稱加密

import base64

s = 'hello, world'
s = "你好"
# 加密
bs = base64.b64encode(s.encode("utf8"))
print(bs)

# 解密
decode = base64.b64decode(bs)
print(decode)
print(decode.decode("utf8"))

MD5

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

md5,其實就是一種演算法。可以將一個字元串,或文件,或壓縮包,執行md5後,就可以生成一個固定長度為128bit的串。這個串,基本上是唯一的。

說明

  • 壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
  • 容易計算:從原數據計算出MD5值很容易。
  • 抗修改性:對原數據進行任何改動,哪怕只修改1個位元組,所得到的MD5值都有很大區別。
  • 強抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。
  • 不可逆性:每個人都有不同的指紋,看到這個人,可以得出他的指紋等信息,並且唯一對應,但你只看一個指紋,是不可能看到或讀到這個人的長相或身份等信息。

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的長度,預設為128bit,也就是128個0和1的二進位串。這樣表達是很不友好的。所以將二進位轉成了16進位,每4個bit表示一個16進位,所以128/4 = 32 換成16進位表示後,為32位了。

為什麼網上還有md5是16位的呢?

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

DES

介紹PyCrypto

PyCrypto是 Python 中密碼學方面最有名的第三方軟體包,提供了許多加密演算法的使用。可惜的是,它的開發工作於2012年就已停止。

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

安裝與導入

安裝之前需要先安裝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運算(第8、16、24、32、40、48、56、64位是校驗位,使得每個密鑰都有奇數個1),分組後的明文組和56位的密鑰按位替代或交換的方法形成密文組。

加密原理

DES 使用一個 56 位的密鑰以及附加的 8 位奇偶校驗位,產生最大 64 位的分組大小。這是一個迭代的分組密碼,使用稱為 Feistel 的技術,其中將加密的文本塊分成兩半。使用子密鑰對其中一半應用迴圈功能,然後將輸出與另一半進行“異或”運算;接著交換這兩半,這一過程會繼續下去,但最後一個迴圈不交換。DES 使用 16 個迴圈,使用異或,置換,代換,移位操作四種基本運算。

演算法步驟

1)初始置換

其功能是把輸入的64位數據塊按位重新組合,並把輸出分為L0、R0兩部分,每部分各長3 2位,其置換規則為將輸入的第58位換到第一位,第50位換到第2位……依此類推,最後一位是原來的第7位。L0、R0則是換位輸出後的兩部分,L0是輸出的左32位,R0是右32位,例:設置換前的輸入值為D1D2D3……D64,則經過初始置換後的結果為:L0=D58D50……D8;R0=D57D49……D7。
其置換規則見下表:
58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,

2)逆置換

經過16次迭代運算後,得到L16、R16,將此作為輸入,進行逆置換,逆置換正好是初始置換的逆運算,由此即得到密文輸出。
此演算法是對稱加密演算法體系中的代表,在電腦網路系統中廣泛使用.

DES加密與解密

# 導入DES模塊
from Cryptodome.Cipher import DES
import binascii

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

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

3DES

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. 設計簡單。

AES加密與解碼

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

一般常用的是128位

from Cryptodome.Cipher import AES
from Cryptodome import Random

from binascii import a2b_hex

# 要加密的明文
data = '南來北往'
# 密鑰key必須為 16(AES-128), 24(AES-192), 32(AES-256)
key = b'this is a 16 key'
# 生成長度等於AES 塊大小的不可重覆的密鑰向量
iv = Random.new().read(AES.block_size)
print(iv)
# 使用 key 和iv 初始化AES 對象, 使用MODE_CFB模式
mycipher = AES.new(key, AES.MODE_CFB, iv)
print(mycipher)
# 加密的明文長度必須為16的倍數, 如果長度不為16的倍數, 則需要補足為16的倍數
# 將iv(密鑰向量)加到加密的密鑰開頭, 一起傳輸
ciptext = iv + mycipher.encrypt(data.encode())
# 解密的話需要用key 和iv 生成的AES對象
print(ciptext)
mydecrypt = AES.new(key, AES.MODE_CFB, ciptext[:16])
# 使用新生成的AES 對象, 將加密的密鑰解密
decrytext = mydecrypt.decrypt(ciptext[16:])

print(decrytext.decode())

RSA

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

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

非對稱加密

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

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

但是演算法的效率低,所以常用於很重要數據的加密,常和對稱配合使用,使用非對稱加密的密鑰去加密對稱加密的密鑰。

RSA加密與解密

首先我們需要安裝一個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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在用到el-tree的懶載入和預設勾選功能時,若第一次勾選前幾個連續節點,第二次進入預設勾選時,由於el-tree子節點尚未完全載入(只載入出來前幾個),預設勾選已經開始(已載入出來的子節點被預設勾選),這時el-tree會認為子節點全部勾選,所以父節點也被勾選,這就導致所有子節點都被勾選; 解決方 ...
  • 本篇不會過多講述 ts 語法,著重記錄下 在 React 中使用 ts 的方法以及踩坑經過。 ...
  • 0.效果演示 插入視頻插不進來,就很煩。可以出門右拐去優酷看下(點我!)。 1.準備工作 1.1前端框架 前端使用了基於vue.js的nuxt.js。為什麼使用nuxt.js? 首先我做的是博客的項目,所以SSR至關重要。雖然跟本文要講的登錄註冊沒有什麼關係,但是文章如果用axios來非同步獲取的話, ...
  • X 維度本身超出了技術範疇,但為了更好地服務業務,技術人也有必要懂得一些基礎的業務優化思路。如果只知道埋頭趕路,不知道抬頭看天,那我們技術人很容易做了費力不討好的事情,例如:某些性能瓶頸是由於業務流程設計不合理導致的,在業務流程優化完善之前,我們僅僅從技術視角去優化改善,極有可能事倍功半。具體說來,... ...
  • 意圖 原型模式是創建型設計模式,可以複製已存在的對象而無需依賴它的類。 問題 假如現在有一個對象,我們想完全複製一份新的,我們該如何做? 1. 創建同一個類的新對象 2. 遍歷所有已存在對象的值,然後將他們的值複製到新對象。 很好,但是我們會發現存在如下問題: 1. 該對象的值並不一定全對對外開放, ...
  • 一、StringBuffer和StringBuilder 1.StringBuffer是什麼? 答:是一個字元串緩衝區,工作原理:預先在記憶體中申請一塊空間以容納字元序列,如果預留的空間,則進行自動擴容,以容納更多的字元序列。 2.StringBuffer\StringBuilder和String最大 ...
  • 如果你對自己手速和市面上的各種 “加速包” 都沒什麼信心的話,不妨試試用程式員的手段搶票? 況且,[12306 官方宣佈屏蔽了一大批付費搶票軟體],這也意味著你即使給這些軟體付了會員費,也依舊搶不到票。 所以只能回到最初的手動搶票?No!No!No! GitHub 上有兩個 “年經” 項目,每到春運 ...
  • 一、HashMap(JDK1.8) 1、基本知識、數據結構 (1)時間複雜度:用來衡量演算法的運行時間。 參考:https://blog.csdn.net/qq_41523096/article/details/82142747 (2)數組:採用一段連續的存儲空間來存儲數據。查找方便,增刪麻煩。 (3 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...