Python加密與解密


加密算法分類

對稱加密算法:

對稱加密采用了對稱密碼編碼技術,它的特點是文件加密和解密使用相同的密鑰
發送方和接收方需要持有同一把密鑰,發送消息和接收消息均使用該密鑰。
相對於非對稱加密,對稱加密具有更高的加解密速度,但雙方都需要事先知道密鑰,密鑰在傳輸過程中可能會被竊取,因此安全性沒有非對稱加密高。
常見的對稱加密算法:DES,AES,3DES等等

非對稱加密算法:

文件加密需要公開密鑰(publickey)和私有密鑰(privatekey)。
接收方在發送消息前需要事先生成公鑰和私鑰,然后將公鑰發送給發送方。發送放收到公鑰后,將待發送數據用公鑰加密,發送給接收方。接收到收到數據后,用私鑰解密。
在這個過程中,公鑰負責加密,私鑰負責解密,數據在傳輸過程中即使被截獲,攻擊者由於沒有私鑰,因此也無法破解。
非對稱加密算法的加解密速度低於對稱加密算法,但是安全性更高。
非對稱加密算法:RSA、DSA、ECC等算法

消息摘要算法:

消息摘要算法可以驗證信息是否被篡改。
在數據發送前,首先使用消息摘要算法生成該數據的簽名,然后簽名和數據一同發送給接收者。
接收者收到數據后,對收到的數據采用消息摘要算法獲得簽名,最后比較簽名是否一致,以此來判斷數據在傳輸過程中是否發生修改。

DES加密

全稱為Data EncryptionStandard,即數據加密標准,是一種使用密鑰加密的塊算法

入口參數有三個:Key、Data、Mode

Key為7個字節共56位,是DES算法的工作密鑰;

Data為8個字節64位,是要被加密或被解密的數據;

Mode為DES的工作方式,有兩種:加密或解密

3DES(即Triple DES)是DES向AES過渡的加密算法,

使用兩個密鑰,執行三次DES算法,

加密的過程是加密-解密-加密

解密的過程是解密-加密-解密

from Crypto.Cipher import DES

key = b'abcdefgh'  # 密鑰 8位或16位,必須為bytes


def pad(text):
    """
    # 加密函數,如果text不是8的倍數【加密文本text必須為8的倍數!】,那就補足為8的倍數
    :param text: 
    :return: 
    """
    while len(text) % 8 != 0:
        text += ' '
    return text


des = DES.new(key, DES.MODE_ECB)  # 創建一個DES實例
text = 'Python rocks!'
padded_text = pad(text)
encrypted_text = des.encrypt(padded_text.encode('utf-8'))  # 加密
print(encrypted_text)
# rstrip(' ')返回從字符串末尾刪除所有字符串的字符串(默認空白字符)的副本
plain_text = des.decrypt(encrypted_text).decode().rstrip(' ')  # 解密
print(plain_text)
#

AES加密

高級加密標准(英語:Advanced EncryptionStandard,縮寫:AES),這個標准用來替代原先的DES

AES的區塊長度固定為128 比特,密鑰長度則可以是128,192或256比特(16、24和32字節)

大致步驟如下:

1、密鑰擴展(KeyExpansion),

2、初始輪(Initial Round),

3、重復輪(Rounds),每一輪又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,

4、最終輪(Final Round),最終輪沒有MixColumns。

普通方式

from Cryptodome.Cipher import AES
from binascii import b2a_hex, a2b_hex
#秘鑰,此處需要將字符串轉為字節
key = 'abcdefgh'
#加密內容需要長達16位字符,所以進行空格拼接
def pad(text):
    while len(text) % 16 != 0:
        text += ' '
    return text
#加密秘鑰需要長達16位字符,所以進行空格拼接
def pad_key(key):
    while len(key) % 16 != 0:
        key += ' '
    return key
#進行加密算法,模式ECB模式,把疊加完16位的秘鑰傳進來
aes = AES.new(pad_key(key).encode(), AES.MODE_ECB)
#加密內容,此處需要將字符串轉為字節
text = 'hello'
#進行內容拼接16位字符后傳入加密類中,結果為字節類型
encrypted_text = aes.encrypt(pad(text).encode())
encrypted_text_hex = b2a_hex(encrypted_text)
print(encrypted_text_hex)


# #此處是為了驗證是否能將字節轉為字符串后,進行解密成功
# #實際上a 就是 encrypted_text ,也就是加密后的內容
# #用aes對象進行解密,將字節類型轉為str類型,錯誤編碼忽略不計
de = str(aes.decrypt(a2b_hex(encrypted_text_hex)), encoding='utf-8',errors="ignore")
# #獲取str從0開始到文本內容的字符串長度。
print(de[:len(text)])

面向對象方式

from Cryptodome.Cipher import AES
from binascii import b2a_hex, a2b_hex

AES_LENGTH = 16

class prpcrypt():
    def __init__(self, key):
        self.key = key
        self.mode = AES.MODE_ECB
        self.cryptor = AES.new(self.pad_key(self.key).encode(), self.mode)

    # 加密函數,如果text不是16的倍數【加密文本text必須為16的倍數!】,那就補足為16的倍數
    # 加密內容需要長達16位字符,所以進行空格拼接
    def pad(self,text):
        while len(text) % AES_LENGTH != 0:
            text += ' '
        return text

    # 加密密鑰需要長達16位字符,所以進行空格拼接
    def pad_key(self,key):
        while len(key) % AES_LENGTH != 0:
            key += ' '
        return key

    def encrypt(self, text):

        # 這里密鑰key 長度必須為16(AES-128)、24(AES-192)、或32(AES-256)Bytes 長度.目前AES-128足夠用
        # 加密的字符需要轉換為bytes
        # print(self.pad(text))
        self.ciphertext = self.cryptor.encrypt(self.pad(text).encode())
        # 因為AES加密時候得到的字符串不一定是ascii字符集的,輸出到終端或者保存時候可能存在問題
        # 所以這里統一把加密后的字符串轉化為16進制字符串
        return b2a_hex(self.ciphertext)

        # 解密后,去掉補足的空格用strip() 去掉

    def decrypt(self, text):
        plain_text = self.cryptor.decrypt(a2b_hex(text)).decode()
        return plain_text.rstrip(' ')


if __name__ == '__main__':
    pc = prpcrypt('abcdef')  # 初始化密鑰
    e = pc.encrypt("0123456789ABCDEF")
    d = pc.decrypt(e)
    print(e, d)
    e = pc.encrypt("00000000000000000000000000")
    d = pc.decrypt(e)
    print(e, d)

RSA加密

公鑰加密算法,一種非對稱密碼算法

公鑰加密,私鑰解密

3個參數:

rsa_n, rsa_e,message

rsa_n, rsa_e 用於生成公鑰

message: 需要加密的消息

安裝 pip install rsa

使用

import rsa
from binascii import b2a_hex, a2b_hex



class rsacrypt():
    def __init__(self, pubkey, prikey):
        self.pubkey = pubkey
        self.prikey = prikey

    def encrypt(self, text):
        self.ciphertext = rsa.encrypt(text.encode(), self.pubkey)
        # 因為rsa加密時候得到的字符串不一定是ascii字符集的,輸出到終端或者保存時候可能存在問題
        # 所以這里統一把加密后的字符串轉化為16進制字符串
        return b2a_hex(self.ciphertext)

    def decrypt(self, text):
        decrypt_text = rsa.decrypt(a2b_hex(text), prikey)
        return decrypt_text


if __name__ == '__main__':
    pubkey, prikey = rsa.newkeys(256)
    rs_obj = rsacrypt(pubkey,prikey)
    text='hello'
    ency_text = rs_obj.encrypt(text)
    print(ency_text)
    print(rs_obj.decrypt(ency_text))

"""
b'7cb319c67853067abcd16aad25b3a8658e521f83b1e6a6cf0c4c2e9303ad3e14'
b'hello'
"""

 


免責聲明!

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



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