PYTHON AES 加密算法


是否需要在Python中使用密碼或私鑰加密某些文本? 您當然來對了地方。 AES-256是一種固態對稱密碼,通常用於為自己加密數據。 換句話說,正在加密數據的同一個人通常也將其解密(請考慮密碼管理器 )。

依存關系

對於本教程,我們將使用Python 3,因此請確保安裝pycryptodome ,這將使我們能夠訪問AES-256的實現:

pip3 install pycryptodomex

填充-由GCM處理

AES-256通常要求以16個字節的塊提供要加密的數據,您可能已經在其他站點或教程中看到了。 但是,在GCM模式下,AES-256不需要任何特殊填充即可由我們手動完成。

正在加密

現在我們創建一個簡單的crypto(plain_text,password)函數。 此功能使用密碼來加密純文本。 因此,任何有權訪問加密文本和密碼的人都可以對其解密。

# AES 256 encryption/decryption using pycryptodome library
 
from base64 import b64encode, b64decode
import hashlib
from Cryptodome.Cipher import AES
import os
from Cryptodome.Random import get_random_bytes
 
def encrypt (plain_text, password) :
    # generate a random salt
    salt = get_random_bytes(AES.block_size)
 
    # use the Scrypt KDF to get a private key from the password
    private_key = hashlib.scrypt(
        password.encode(), salt=salt, n= 2 ** 14 , r= 8 , p= 1 , dklen= 32 )
 
    # create cipher config
    cipher_config = AES.new(private_key, AES.MODE_GCM)
 
    # return a dictionary with the encrypted text
    cipher_text, tag = cipher_config.encrypt_and_digest(bytes(plain_text, 'utf-8' ))
    return {
        'cipher_text' : b64encode(cipher_text).decode( 'utf-8' ),
        'salt' : b64encode(salt).decode( 'utf-8' ),
        'nonce' : b64encode(cipher_config.nonce).decode( 'utf-8' ),
        'tag' : b64encode(tag).decode( 'utf-8' )
    }
 
 
def decrypt (enc_dict, password) :
    # decode the dictionary entries from base64
    salt = b64decode(enc_dict[ 'salt' ])
    cipher_text = b64decode(enc_dict[ 'cipher_text' ])
    nonce = b64decode(enc_dict[ 'nonce' ])
    tag = b64decode(enc_dict[ 'tag' ])
    
 
    # generate the private key from the password and salt
    private_key = hashlib.scrypt(
        password.encode(), salt=salt, n= 2 ** 14 , r= 8 , p= 1 , dklen= 32 )
 
    # create the cipher config
    cipher = AES.new(private_key, AES.MODE_GCM, nonce=nonce)
 
    # decrypt the cipher text
    decrypted = cipher.decrypt_and_verify(cipher_text, tag)
 
    return decrypted
 
 
def main () :
    password = input( "Password: " )
 
    # First let us encrypt secret message
    encrypted = encrypt( "The secretest message here" , password)
    print(encrypted)
 
    # Let us decrypt using our original password
    decrypted = decrypt(encrypted, password)
    print(bytes.decode(decrypted))
 
main()

有關crypto()函數的注意事項

  1. 隨機數 :一個隨機數(任意值)必須是我們的加密功能使用相同的密鑰每次隨機和獨特的價值。 可以將其視為密碼的隨機鹽。 圖書館為我們提供了安全的隨機數。
  2. Scrypt :Scrypt用於從密碼生成安全私鑰。 這將使攻擊者更難於暴力破解我們的加密。
  3. 鹽 :每次加密都會使用新的隨機鹽。 這使得攻擊者無法使用預先計算的哈希來破解密碼。 ( 見彩虹表 )
  4. 加密參數 :
  1. N是成本因素。 它必須是2的冪,並且它越高,密鑰就越安全,但是需要更多的資源來運行。
  2. R是塊大小。
  3. P是並行化因子,可用於在多個內核上運行。
  1. Base64 :我們將所有字節類型的數據編碼為方便的字符串表示形式的base64
  2. 標簽 :在GCM模式下使用AES時,標簽用於驗證數據。 這樣可以確保在解密時沒有人不知道我們就無法更改我們的數據。
    crypto()函數需要使用與加密相同的鹽,隨機數和標記。 為了方便解析,我們使用了字典,但是如果我們想要一串密文,則可以使用諸如salt.nonce.tag.cipher_text之類的方案。Scrypt和AES函數上的配置參數必須與crypto函數相同。 


免責聲明!

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



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