杰瑞科技汇

python public keys

Of course! Let's dive into a comprehensive guide to public keys in Python.

python public keys-图1
(图片来源网络,侵删)

We'll cover three main aspects:

  1. The Core Concept: What are public keys and why are they important?
  2. Practical Cryptography with Python: How to generate, use, and manage keys using the standard library and popular third-party libraries.
  3. Real-World Example: A complete, runnable example of a simple secure chat application.

The Core Concept: Public Key Cryptography

Imagine a mailbox with a special lock:

  • Public Key: Anyone can get a copy of this key. You can post it on your website, email it to friends, etc. This key can only be used to put mail into the box. It cannot be used to open the box.
  • Private Key: This is the only key that can open the mailbox. You must keep this secret. You use it to take mail out of the box.

This is the fundamental idea behind public key cryptography, also known as asymmetric cryptography.

Key Properties:

  • Confidentiality (Encryption): If I want to send you a secret message, I encrypt it with your public key. Only the person with the corresponding private key (you) can decrypt it.
  • Authentication & Integrity (Digital Signatures): If you want to prove a message came from you, you "sign" it with your private key. Anyone can then verify this signature using your public key. This proves it was you (authentication) and that the message wasn't tampered with (integrity).

Common Algorithms:

  • RSA: The classic and most widely known algorithm. Great for encrypting small amounts of data (like a symmetric key) and for creating digital signatures.
  • ECC (Elliptic Curve Cryptography): A more modern and efficient alternative to RSA. It provides the same level of security with much smaller key sizes, making it faster and using less memory. Ideal for mobile and embedded devices.
  • DSA (Digital Signature Algorithm): Specifically designed for creating digital signatures.

Practical Cryptography in Python

Python offers excellent tools for this. We'll start with the built-in cryptography library, which is the modern standard.

python public keys-图2
(图片来源网络,侵删)

Step 1: Installation

If you don't have it installed, open your terminal or command prompt and run:

pip install cryptography

Step 2: Generating Key Pairs

The cryptography library provides a high-level, user-friendly API. The easiest way to generate keys is using the Fernet class, which handles all the complexities for you. Fernet is a high-level symmetric recipe that uses a public key to securely exchange the symmetric key.

However, for a more direct look at public/private keys, let's use the rsa library first, then show the easier cryptography way.

Method A: Using the rsa library (More Direct)

First, install it:

python public keys-图3
(图片来源网络,侵删)
pip install rsa

Now, let's generate a key pair:

import rsa
# Generate a public/private key pair
# Key size is in bits. 2048 is a good standard for RSA.
public_key, private_key = rsa.newkeys(2048)
print("Public Key:")
print(public_key.save_pkcs1().decode('utf-8'))
print("\nPrivate Key:")
print(private_key.save_pkcs1().decode('utf-8'))

This will print out your public and private keys in the standard PEM format.

Method B: Using the cryptography library (Recommended)

The cryptography library is more robust and the industry standard. Here's how to generate an RSA key pair.

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
# 1. Generate a private key
private_key = rsa.generate_private_key(
    public_exponent=65537,  # A standard, secure value
    key_size=2048,
)
# 2. Get the public key from the private key
public_key = private_key.public_key()
# 3. Serialize the keys to save them to files or use them
# Serialize the public key to PEM format
public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
# Serialize the private key to PEM format
# IMPORTANT: Use BestAvailableEncryption to protect your private key with a password
private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.BestAvailableEncryption(b"super-secret-password") # Use a strong password!
)
# You can now save these to files
with open("public_key.pem", "wb") as f:
    f.write(public_pem)
with open("private_key.pem", "wb") as f:
    f.write(private_pem)
print("Public and private keys have been saved to files.")

Step 3: Encrypting and Decrypting

Now let's use the keys we generated.

from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
# Assume you have the public and private keys loaded from files
# For this example, we'll generate them again
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# The message you want to send (must be bytes)
message = b"This is a secret message that only the owner of the private key can read."
# --- ENCRYPTION ---
# Encrypt the message using the PUBLIC KEY
# OAEP padding is a modern, secure padding scheme
ciphertext = public_key.encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print(f"Original message: {message}")
print(f"Encrypted message (ciphertext): {ciphertext}")
print("-" * 30)
# --- DECRYPTION ---
# Decrypt the ciphertext using the PRIVATE KEY
# Note: The same padding and hash algorithm must be used
plaintext = private_key.decrypt(
    ciphertext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print(f"Decrypted message: {plaintext}")

Step 4: Digital Signatures

Let's sign a message with our private key and verify it with our public key.

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.exceptions import InvalidSignature
# Assume you have the private and public keys
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
message = b"I, Alice, authorize payment to Bob for $100."
# --- SIGNING ---
# Sign the message using the PRIVATE KEY
# PSS is a secure padding scheme for signatures
signature = private_key.sign(
    message,
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH
    ),
    hashes.SHA256()
)
print(f"Message: {message}")
print(f"Signature: {signature}")
print("-" * 30)
# --- VERIFICATION ---
# Verify the signature using the PUBLIC KEY
try:
    public_key.verify(
        signature,
        message,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    print("SUCCESS: The signature is valid.")
except InvalidSignature:
    print("FAILURE: The signature is invalid!")
# --- TAMPERING DETECTION ---
# Let's change the message slightly and try to verify again
tampered_message = b"I, Alice, authorize payment to Bob for $1,000." # Changed $100 to $1,000
try:
    public_key.verify(
        signature,
        tampered_message,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    print("SUCCESS: The signature is valid.")
except InvalidSignature:
    print("FAILURE: The signature is invalid! (Tampering detected)")

Real-World Example: Simple Secure Chat

This example shows how two parties, Alice and Bob, can exchange a secret message securely using public keys.

Scenario:

  1. Alice generates a key pair and sends her public key to Bob.
  2. Bob wants to send a secret message to Alice.
  3. Bob encrypts his message with Alice's public key.
  4. Bob sends the encrypted message to Alice.
  5. Alice uses her private key to decrypt the message.
# --- setup_alice.py ---
# This script runs on Alice's machine to generate and share her public key.
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
def generate_and_save_alice_keys():
    """Generates a key pair for Alice and saves them."""
    print("Alice is generating her key pair...")
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    public_key = private_key.public_key()
    # Save Alice's private key (keep this secret!)
    with open("alice_private_key.pem", "wb") as f:
        f.write(private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption() # No password for simplicity
        ))
    # Save Alice's public key to share with Bob
    with open("alice_public_key.pem", "wb") as f:
        f.write(public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        ))
    print("Alice's keys have been saved.")
    print("alice_public_key.pem is ready to be sent to Bob.")
# generate_and_save_alice_keys()
# --- bob_send_message.py ---
# This script runs on Bob's machine to send a secure message to Alice.
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.hazmat.primitives import hashes
def bob_send_secure_message():
    """Bob loads Alice's public key and sends her an encrypted message."""
    print("Bob is preparing to send a message to Alice...")
    # 1. Bob loads Alice's PUBLIC KEY
    with open("alice_public_key.pem", "rb") as f:
        alice_public_pem = f.read()
    alice_public_key = serialization.load_pem_public_key(alice_public_pem)
    # 2. Bob creates his secret message
    message = b"Hello Alice, this is a secret message from Bob!"
    # 3. Bob encrypts the message with Alice's public key
    ciphertext = alice_public_key.encrypt(
        message,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    # 4. Bob "sends" the ciphertext. In a real app, this would be over a network.
    # For this example, we'll just save it to a file.
    with open("message_for_alice.bin", "wb") as f:
        f.write(ciphertext)
    print("Bob has encrypted the message and sent 'message_for_alice.bin' to Alice.")
    print(f"The original message was: {message}")
# bob_send_secure_message()
# --- alice_read_message.py ---
# This script runs on Alice's machine to read the message from Bob.
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.hazmat.primitives import hashes
def alice_read_secure_message():
    """Alice loads her private key and decrypts the message from Bob."""
    print("Alice is reading her message from Bob...")
    # 1. Alice loads her PRIVATE KEY
    with open("alice_private_key.pem", "rb") as f:
        alice_private_pem = f.read()
    alice_private_key = serialization.load_pem_private_key(
        alice_private_pem,
        password=None # No password was used
    )
    # 2. Alice loads the encrypted message
    with open("message_for_alice.bin", "rb") as f:
        ciphertext = f.read()
    # 3. Alice decrypts the message with her private key
    plaintext = alice_private_key.decrypt(
        ciphertext,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    print("Alice has successfully decrypted the message!")
    print(f"The decrypted message is: {plaintext}")
# alice_read_secure_message()

To run this example:

  1. Save the three code blocks as setup_alice.py, bob_send_message.py, and alice_read_message.py.
  2. Run python setup_alice.py. This will create alice_private_key.pem and alice_public_key.pem.
  3. Run python bob_send_message.py. This will create message_for_alice.bin.
  4. Run python alice_read_message.py. This will read the file and decrypt the message, printing the original text.

Summary

Task Python Library Key Used Result
Generate Keys cryptography or rsa N/A A public_key and private_key object
Encrypt cryptography Public ciphertext (unreadable bytes)
Decrypt cryptography Private plaintext (original message)
Sign cryptography Private signature (unique digital fingerprint)
Verify cryptography Public True or InvalidSignature exception

Public key cryptography is a cornerstone of modern internet security, enabling everything from HTTPS (TLS/SSL) to secure messaging and cryptocurrency. Python's cryptography library makes it accessible and safe to use in your own applications.

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