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函数相同。 
posted @ 2022-03-23 05:48  myrj  阅读(1625)  评论(0编辑  收藏  举报