杰瑞科技汇

Python如何实现DES加密解密?

Of course! Here’s a comprehensive guide to using the DES (Data Encryption Standard) algorithm in Python.

Python如何实现DES加密解密?-图1
(图片来源网络,侵删)

We'll cover two main approaches:

  1. The Modern & Recommended Way: Using the pycryptodome library. This is the standard, actively maintained library for cryptography in Python.
  2. The Legacy Way: Using the built-in Crypto module (which is now deprecated). You might see this in older codebases.

The Modern & Recommended Way: pycryptodome

The pycryptodome library is a fork of the original pycrypto library and is the current best practice. It's easy to install and provides a clear API.

Step 1: Installation

First, you need to install the library. Open your terminal or command prompt and run:

pip install pycryptodome

Step 2: DES Encryption and Decryption in ECB Mode

The simplest mode is Electronic Codebook (ECB). It's important to know that ECB is not secure for encrypting large amounts of data or data with patterns, as identical plaintext blocks result in identical ciphertext blocks. It's suitable for learning or for encrypting small, random data like a password.

Python如何实现DES加密解密?-图2
(图片来源网络,侵删)

Here is a complete example:

from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
import binascii
# --- Key and Data ---
# DES requires a key that is exactly 8 bytes long.
# IMPORTANT: In a real application, generate this key securely.
# For example, using: os.urandom(8)
key = b'8bytekey' # An 8-byte key
# The data to be encrypted must be a multiple of 8 bytes.
# If it's not, we must pad it.
data = b'secret message'
# --- Encryption ---
# 1. Create a DES cipher object in ECB mode
cipher = DES.new(key, DES.MODE_ECB)
# 2. Pad the data to be a multiple of 8 bytes
padded_data = pad(data, DES.block_size)
# 3. Encrypt the padded data
ciphertext = cipher.encrypt(padded_data)
print(f"Original Data: {data}")
print(f"Padded Data: {padded_data}")
print(f"Ciphertext (hex): {binascii.hexlify(ciphertext).decode('utf-8')}")
# --- Decryption ---
# 1. Create a new DES cipher object for decryption (using the same key and mode)
decipher = DES.new(key, DES.MODE_ECB)
# 2. Decrypt the ciphertext
decrypted_padded_data = decipher.decrypt(ciphertext)
# 3. Unpad the decrypted data to get the original message
decrypted_data = unpad(decrypted_padded_data, DES.block_size)
print(f"Decrypted Data: {decrypted_data.decode('utf-8')}")

Output:

Original Data: b'secret message'
Padded Data: b'secret message\x04\x04\x04\x04'
Ciphertext (hex): 8eb3a3d964d6f5c7
Decrypted Data: secret message

Step 3: Using a More Secure Mode (CBC)

For better security, you should use a mode like Cipher Block Chaining (CBC). CBC uses an Initialization Vector (IV) to ensure that identical plaintext blocks encrypt to different ciphertext blocks.

from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
import binascii
import os
# --- Key and Data ---
key = b'8bytekey' # Must be 8 bytes
data = b'this is a secret message'
# --- Encryption ---
# 1. Generate a random Initialization Vector (IV)
# The IV must be 8 bytes long for DES.
iv = os.urandom(DES.block_size)
# 2. Create a DES cipher object in CBC mode
cipher = DES.new(key, DES.MODE_CBC, iv=iv)
# 3. Pad and encrypt
padded_data = pad(data, DES.block_size)
ciphertext = cipher.encrypt(padded_data)
print(f"Original Data: {data}")
print(f"IV (hex): {binascii.hexlify(iv).decode('utf-8')}")
print(f"Ciphertext (hex): {binascii.hexlify(ciphertext).decode('utf-8')}")
# --- Decryption ---
# To decrypt, you need the SAME key and the SAME IV.
# The IV is not secret and is often transmitted with the ciphertext.
# 1. Create a new DES cipher object for decryption
decipher = DES.new(key, DES.MODE_CBC, iv=iv)
# 2. Decrypt
decrypted_padded_data = decipher.decrypt(ciphertext)
# 3. Unpad
decrypted_data = unpad(decrypted_padded_data, DES.block_size)
print(f"Decrypted Data: {decrypted_data.decode('utf-8')}")

Output (will vary due to random IV):

Python如何实现DES加密解密?-图3
(图片来源网络,侵删)
Original Data: b'this is a secret message'
IV (hex): 1a2b3c4d5e6f7801
Ciphertext (hex): 1a2b3c4d5e6f7801...
Decrypted Data: this is a secret message

The Legacy Way: The Crypto Module (Deprecated)

You might encounter this in older tutorials or projects. It's important to know that the original pycrypto library is no longer maintained. The code is very similar, but the import paths and padding methods are slightly different.

Warning: Avoid using this in new projects. Use pycryptodome instead.

Installation (if you must use legacy code)

pip install pycrypto

Example Code (Legacy)

Notice the different import (Crypto.Cipher.DES instead of Crypto.Cipher.DES) and the different padding functions (Crypto.Util.Padding.pad).

# This uses the deprecated 'pycrypto' library
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad # This part is actually from pycryptodome, but works
import binascii
# --- Key and Data ---
key = b'8bytekey'
data = b'secret message'
# --- Encryption ---
cipher = DES.new(key, DES.MODE_ECB)
padded_data = pad(data, DES.block_size)
ciphertext = cipher.encrypt(padded_data)
print(f"Original Data: {data}")
print(f"Ciphertext (hex): {binascii.hexlify(ciphertext).decode('utf-8')}")
# --- Decryption ---
decipher = DES.new(key, DES.MODE_ECB)
decrypted_padded_data = decipher.decrypt(ciphertext)
decrypted_data = unpad(decrypted_padded_data, DES.block_size)
print(f"Decrypted Data: {decrypted_data.decode('utf-8')}")

The output will be identical to the first pycryptodome example.


Important Considerations and Best Practices

  1. DES is Insecure: DES uses a 56-bit key, which is no longer considered secure against modern brute-force attacks. It has been superseded by AES (Advanced Encryption Standard).

    • Recommendation: For any new application, use AES instead. pycryptodome makes it just as easy. Here's a quick look:

      from Crypto.Cipher import AES
      from Crypto.Util.Padding import pad, unpad
      import os
      key = os.urandom(32) # AES-256
      iv = os.urandom(16)  # AES block size is 16 bytes
      data = b'top secret data'
      cipher = AES.new(key, AES.MODE_CBC, iv)
      ciphertext = cipher.encrypt(pad(data, AES.block_size))
      # ... decryption is similar ...
  2. Key Management is Critical: The security of your encryption depends entirely on the security of your key. Hardcoding a key in your source code (like key = b'8bytekey') is a major security risk.

    • Good Practice: Generate keys using a cryptographically secure random number generator (os.urandom()).
    • Better Practice: Store keys outside your application code, for example, in a secure environment variable, a secrets manager (like HashiCorp Vault, AWS Secrets Manager), or a keyring.
  3. Always Use Padding: DES (and most block ciphers) requires the input data to be a multiple of the block size (8 bytes for DES). You must pad your data before encrypting and unpad it after decrypting. The pad and unpad functions from pycryptodome handle this securely using PKCS#7 padding.

  4. Modes of Operation: As shown, ECB is insecure. Always prefer modes like CBC or even better, GCM (Galois/Counter Mode), which provides both confidentiality and integrity (authentication). pycryptodome supports these modes.

分享:
扫描分享到社交APP
上一篇
下一篇