Blog | G5 Cyber Security

Public Key Encryption: Secure Communication

TL;DR

You want to send secure messages where anyone can verify them (using a public key), but only you can create them. This guide explains how to use asymmetric encryption with a public decryption key and a private encryption key, making it impossible for someone knowing the public key to forge messages.

How It Works

Asymmetric encryption uses two keys: a public key and a private key. The public key can be shared with anyone. The private key must be kept secret. In this scenario, we’ll use the public key for decryption and the private key for encryption – which is less common but meets your specific requirement.

Step-by-Step Guide

  1. Choose an Asymmetric Encryption Algorithm: RSA is a popular choice. ECC (Elliptic Curve Cryptography) is another option, often faster and more efficient for the same level of security.
  2. Generate Key Pair: Use a cryptography library to generate your key pair. The size of the key (e.g., 2048 bits for RSA) determines the strength of the encryption. Larger keys are harder to crack but slower.
    openssl genrsa -out private.pem 2048
    openssl rsa -in private.pem -pubout -out public.pem
  3. Encryption (using your Private Key): This is where you ‘sign’ the message. You use your private key to encrypt the data.

    Example using OpenSSL:

    openssl rsautl -encrypt -inkey private.pem -pubin -in message.txt -out encrypted.bin
  4. Decryption (using your Public Key): Anyone with the public key can decrypt the data.

    Example using OpenSSL:

    openssl rsautl -decrypt -inkey public.pem -in encrypted.bin -out decrypted.txt
  5. Important Considerations:
    • Padding Schemes: Always use a proper padding scheme (e.g., PKCS#1 v1.5, OAEP) when encrypting with RSA to prevent attacks. The examples above implicitly use PKCS#1 v1.5.
    • Key Storage: Protect your private key! Store it securely – consider using a hardware security module (HSM) or a secure enclave.
    • Message Size: Asymmetric encryption is generally slower than symmetric encryption. For large messages, encrypt the message with a randomly generated symmetric key, then encrypt that symmetric key with your asymmetric key.
    • Library Choice: Use well-vetted cryptography libraries (e.g., OpenSSL, Bouncy Castle, PyCryptodome) to avoid implementing cryptographic functions yourself.

Why This Works

The mathematical properties of asymmetric encryption algorithms ensure that it’s computationally infeasible to derive the private key from the public key. Therefore, knowing the public key doesn’t allow someone to forge messages encrypted with the private key.

Example Scenario (Python)

from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import Encoding, PublicKeyFormat, NoEncryption
import os

# Generate private key
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)

# Extract public key
public_key = private_key.public_key()

# Serialize keys (save to files)
with open('private.pem', 'wb') as f:
    f.write(private_key.private_bytes(
        encoding=Encoding.PEM,
        format=PublicKeyFormat.PKCS8,
        encryption_algorithm=NoEncryption()
    ))

with open('public.pem', 'wb') as f:
    f.write(public_key.public_bytes(
        encoding=Encoding.PEM,
        format=PublicKeyFormat.SubjectPublicKeyInfo()
    ))

# Encryption (using private key)
cryptographer = rsa.PKCS1v15Encryptor(private_key)
message = b'This is a secret message.'
encrypted_message = cryptographer.encrypt(message)
print("Encrypted Message:", encrypted_message)

# Decryption (using public key)
decryptor = rsa.PKCS1v15Decryptor(public_key)
try:
    decrypted_message = decryptor.decrypt(encrypted_message)
    print("Decrypted Message:", decrypted_message.decode())
except ValueError as e:
    print("Decryption Error:", e)
Exit mobile version