Home  >  Article  >  Backend Development  >  How to Ensure Secure Encryption in Python?

How to Ensure Secure Encryption in Python?

DDD
DDDOriginal
2024-10-22 21:29:30898browse

How to Ensure Secure Encryption in Python?

Secure Encryption Using Symmetric Key

The recommended approach for secure encryption in Python is using the Fernet recipe from the cryptography library. It employs AES CBC encryption with HMAC for integrity verification, effectively protecting data from tampering and unauthorized decryption.

Fernet Encryption and Decryption

<code class="python">from cryptography.fernet import Fernet

# Generate a secret key for encryption
key = Fernet.generate_key()

# Encode a message (plaintext)
encoded_message = Fernet(key).encrypt(b"John Doe")

# Decode the encrypted message (ciphertext)
decoded_message = Fernet(key).decrypt(encoded_message)

print(decoded_message.decode())  # Output: John Doe</code>

Password-Derived Fernet Key

While it's recommended to use a randomly generated key for security, you can also derive a key from a password if necessary:

<code class="python">from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes

def derive_key(password):
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=secrets.token_bytes(16),
        iterations=100_000,
        backend=default_backend()
    )
    return b64e(kdf.derive(password.encode()))

# Generate a password using a key derivation function
key = derive_key(password)

# Encrypt and decrypt using the password-derived Fernet key
encoded_message = Fernet(key).encrypt(b"John Doe")
decoded_message = Fernet(key).decrypt(encoded_message)

print(decoded_message.decode())  # Output: John Doe</code>

Obscuring Data

For non-sensitive data, consider using base64 encoding instead of encryption:

<code class="python">from base64 import urlsafe_b64encode as b64e

# Encode data
encoded_data = b64e(b"Hello world!")

# Decode data
decoded_data = b64d(encoded_data)

print(decoded_data)  # Output: b'Hello world!'</code>

Signing Data

Sign data to ensure integrity using HMAC:

<code class="python">import hmac
import hashlib

# Sign data using a secret key
key = secrets.token_bytes(32)
signature = hmac.new(key, b"Data to sign", hashlib.sha256).digest()

# Verify the signature
def verify(data, signature, key):
    expected = hmac.new(key, data, hashlib.sha256).digest()
    return hmac.compare_digest(expected, signature)

# Verify the signature using the same key
print(verify(b"Data to sign", signature, key))  # Output: True</code>

Others: Correct Implementations of Insecure Schemes

AES CFB:

<code class="python">import secrets
from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

backend = default_backend()

def aes_cfb_encrypt(message, key):
    algorithm = algorithms.AES(key)
    iv = secrets.token_bytes(algorithm.block_size // 8)
    cipher = Cipher(algorithm, modes.CFB(iv), backend=backend)
    encryptor = cipher.encryptor()
    return b64e(iv + encryptor.update(message) + encryptor.finalize())

def aes_cfb_decrypt(ciphertext, key):
    iv_ciphertext = b64d(ciphertext)
    algorithm = algorithms.AES(key)
    size = algorithm.block_size // 8
    iv, encrypted = iv_ciphertext[:size], iv_ciphertext[size:]
    cipher = Cipher(algorithm, modes.CFB(iv), backend=backend)
    decryptor = cipher.decryptor()
    return decryptor.update(encrypted) + decryptor.finalize()</code>

AES ECB:

<code class="python">from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend

backend = default_backend()

def aes_ecb_encrypt(message, key):
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
    encryptor = cipher.encryptor()
    padder = padding.PKCS7(cipher.algorithm.block_size).padder()
    padded_message = padder.update(message.encode()) + padder.finalize()
    return b64e(encryptor.update(padded_message) + encryptor.finalize())

def aes_ecb_decrypt(ciphertext, key):
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
    decryptor = cipher.decryptor()
    unpadder = padding.PKCS7(cipher.algorithm.block_size).unpadder()
    padded_message = decryptor.update(b64d(ciphertext)) + decryptor.finalize()
    return unpadder.update(padded_message) + unpadder.finalize()</code>

Note: AES ECB is not recommended for secure encryption.

The above is the detailed content of How to Ensure Secure Encryption in Python?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn