[파이썬] 네트워크 데이터 암호화

With the increasing reliance on network communication, it has become crucial to secure the data being transmitted. One of the most effective ways of achieving this is through encryption. Encryption ensures that even if an unauthorized party intercepts the data, they cannot understand or tamper with it.

In this blog post, we will explore how to implement network data encryption in Python using the cryptography library. This library provides a wide range of cryptographic algorithms, making it a great choice for securing network data.

1. Installation

Before we begin, let’s make sure we have the cryptography library installed. Open your terminal and run the following command:

pip install cryptography

2. Generating Encryption Keys

To encrypt and decrypt data, we need to generate a pair of encryption keys: a public key for encryption and a private key for decryption. Let’s see how to generate these keys using the Elliptic Curve Cryptography (ECC) algorithm:

from cryptography.hazmat.primitives.asymmetric import ec

# Generate ECC key pair
private_key = ec.generate_private_key(ec.SECP256K1())
public_key = private_key.public_key()

# Serialize keys to PEM format
private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption()
)
public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)

# Save keys to files
with open('private_key.pem', 'wb') as private_file:
    private_file.write(private_pem)
    
with open('public_key.pem', 'wb') as public_file:
    public_file.write(public_pem)

In the above code, we generate an ECC key pair using the SECP256K1 curve. We then serialize the keys to PEM format and save them to separate files: private_key.pem for the private key and public_key.pem for the public key.

3. Encrypting and Decrypting Data

Now that we have our encryption keys, let’s see how to use them to encrypt and decrypt network data. We will use the AES (Advanced Encryption Standard) algorithm in CBC (Cipher Block Chaining) mode for symmetric encryption:

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

def encrypt_data(data, public_key_path):
    # Load public key from file
    with open(public_key_path, 'rb') as public_file:
        public_pem = public_file.read()
    public_key = serialization.load_pem_public_key(public_pem)

    # Generate random AES key
    aes_key = os.urandom(32)

    # Initialize AES cipher
    cipher = Cipher(algorithms.AES(aes_key), modes.CBC())

    # Encrypt data
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(data.encode()) + encryptor.finalize()

    # Encrypt AES key with public key
    encrypted_key = public_key.encrypt(
        aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    return ciphertext, encrypted_key


def decrypt_data(ciphertext, encrypted_key, private_key_path):
    # Load private key from file
    with open(private_key_path, 'rb') as private_file:
        private_pem = private_file.read()
    private_key = serialization.load_pem_private_key(private_pem, password=None)

    # Decrypt AES key with private key
    aes_key = private_key.decrypt(
        encrypted_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    # Initialize AES cipher
    cipher = Cipher(algorithms.AES(aes_key), modes.CBC())

    # Decrypt data
    decryptor = cipher.decryptor()
    plaintext = decryptor.update(ciphertext) + decryptor.finalize()

    return plaintext.decode()

In the code above, the encrypt_data function takes a data parameter and the path to the public_key.pem file. It generates a random AES key, encrypts the data using the AES key, and then encrypts the AES key using the public key. The function returns the ciphertext and the encrypted AES key.

The decrypt_data function takes the ciphertext, encrypted AES key, and the path to the private_key.pem file. It decrypts the AES key using the private key and then decrypts the ciphertext using the AES key. The function returns the decrypted plaintext.

4. Putting it all together

With the encryption and decryption functions in place, we can now encrypt and decrypt network data. Let’s see an example:

data = "This is my sensitive data"

# Encrypt data
ciphertext, encrypted_key = encrypt_data(data, 'public_key.pem')

# Transmit ciphertext and encrypted_key over the network

# Decrypt data
plaintext = decrypt_data(ciphertext, encrypted_key, 'private_key.pem')

print(plaintext)  # Output: "This is my sensitive data"

In the example above, we encrypt the data using the public key and then decrypt it using the private key, resulting in the original plaintext.

By implementing network data encryption in Python, we can ensure the confidentiality and integrity of the data being transmitted over the network. This is essential for protecting sensitive information and maintaining the security of our applications.

Remember, encryption is just one aspect of securing network communication. It is important to also consider authentication and secure protocols to build a robust and secure system.

I hope you found this tutorial helpful. Stay tuned for more articles on network security and encryption in Python!