You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何基于密码安全加解密数据?pysodium使用疑问

Using pysodium for Password-Based File Encryption/Decryption in Python

Hey there! You’re on the perfect track picking libsodium (via pysodium) instead of rolling your own crypto—let’s break down how to implement secure password-based encryption and decryption step by step.

Prerequisites

First, make sure you have pysodium installed:

pip install pysodium

Core Concepts

Libsodium doesn’t have a "direct password encrypt" function out of the box, but we’ll combine two battle-tested routines to do this safely:

  • Password hashing (crypto_pwhash): Derives a secure encryption key from your password (never use the password directly as a key—this is the mistake most insecure implementations make!)
  • Authenticated symmetric encryption (crypto_secretbox): Encrypts your data with the derived key, and automatically verifies integrity when decrypting (prevents tampering or corrupted data from being accepted)

Full Implementation Code

Here’s a complete, reusable example with file I/O:

import pysodium
import os

def encrypt_data_with_password(data: bytes, password: str) -> bytes:
    # Generate a random 16-byte salt for key derivation (unique per encryption)
    salt = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES)
    
    # Derive a 32-byte encryption key from the password
    key = pysodium.crypto_pwhash(
        outlen=pysodium.crypto_secretbox_KEYBYTES,
        passwd=password.encode(),
        salt=salt,
        opslimit=pysodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
        memlimit=pysodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
    )
    
    # Generate a random 24-byte nonce (MUST NEVER reuse this with the same key!)
    nonce = pysodium.randombytes(pysodium.crypto_secretbox_NONCEBYTES)
    
    # Encrypt the data with authenticated encryption
    ciphertext = pysodium.crypto_secretbox_easy(data, nonce, key)
    
    # Return salt + nonce + ciphertext (we need salt/nonce for decryption later)
    return salt + nonce + ciphertext

def decrypt_data_with_password(encrypted_data: bytes, password: str) -> bytes:
    # Split the encrypted data into its components
    salt_len = pysodium.crypto_pwhash_SALTBYTES
    nonce_len = pysodium.crypto_secretbox_NONCEBYTES
    
    salt = encrypted_data[:salt_len]
    nonce = encrypted_data[salt_len:salt_len+nonce_len]
    ciphertext = encrypted_data[salt_len+nonce_len:]
    
    # Derive the same key using the password and stored salt
    key = pysodium.crypto_pwhash(
        outlen=pysodium.crypto_secretbox_KEYBYTES,
        passwd=password.encode(),
        salt=salt,
        opslimit=pysodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
        memlimit=pysodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
    )
    
    # Decrypt and verify the data (throws ValueError if password is wrong or data is tampered)
    try:
        plaintext = pysodium.crypto_secretbox_open_easy(ciphertext, nonce, key)
        return plaintext
    except ValueError:
        raise Exception("Decryption failed: wrong password or corrupted/modified data")

# Example usage
if __name__ == "__main__":
    # Encrypt and write to file
    sensitive_data = b"Your private data here—text, JSON, binary files, whatever you need"
    user_password = "your_strong_unique_password_here"
    
    encrypted_content = encrypt_data_with_password(sensitive_data, user_password)
    with open("encrypted_storage.bin", "wb") as f:
        f.write(encrypted_content)
    
    # Read and decrypt from file
    with open("encrypted_storage.bin", "rb") as f:
        stored_encrypted_data = f.read()
    
    decrypted_data = decrypt_data_with_password(stored_encrypted_data, user_password)
    print("Decrypted result:", decrypted_data.decode())

Key Security Tips

  • Never reuse nonces: The nonce must be unique for every encryption with the same key—we generate a new random one each time, which is the safest approach.
  • Tweak opslimit/memlimit: The INTERACTIVE settings balance speed and security for most apps. For long-term sensitive storage, use OPSLIMIT_MODERATE or OPSLIMIT_SENSITIVE (it’ll be slower but harder to brute-force).
  • Handle errors gracefully: The decryption step throws a ValueError if the password is wrong or data was tampered with—make sure to catch this in your code to avoid crashes.
  • Use strong passwords: Even the best crypto can’t save you from a weak, guessable password!

内容的提问来源于stack exchange,提问作者The Quantum Physicist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:36:15