如何使用 PyCryptodome 在 Python 中进行 RSA 加密

问题描述 投票:0回答:1

我是加密世界的新手,我想知道我的加密/解密数据解决方案是否可以。

创建此内容时,我引用了 PyCryptodome 中的 API 文档:https://pycryptodome.readthedocs.io/en/latest/src/api.html

作为参考,我有一个客户端-服务器应用程序,并且假设发送者已经知道主机的公钥。

  1. 将会话密钥、随机数和标签发送给主机是否正确?
  2. 有什么重要的事情是我遗漏/忽视的吗?
def send_data(socket, key, data):
    enc_session_key, nonce, tag, ciphertext = encrypt_data(key, data)
    
    encapsulated_data = [enc_session_key, nonce, tag, ciphertext]
    
    data = pickle.dumps(encapsulated_data)
    
    stream = bytes(data)
    stream_length = len(stream)
    socket.sendall(struct.pack("<Q", stream_length))
    socket.sendall(stream)


def encrypt_data(key, data):
    recipient_key = key
    session_key = get_random_bytes(16)

    # Encrypt the session key with the public RSA key
    cipher_rsa = PKCS1_OAEP.new(recipient_key)
    enc_session_key = cipher_rsa.encrypt(session_key)

    # Encrypt the data with the AES session key
    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(data)

    return enc_session_key, cipher_aes.nonce, tag, ciphertext

def decrypt_data(enc_session_key, nonce, tag, ciphertext):
    if not os.path.exists(PRIVATE_PATH):
        return None

    private_key = RSA.import_key(open(PRIVATE_PATH).read())

    # Decrypt the session key with the private RSA key
    cipher_rsa = PKCS1_OAEP.new(private_key)
    session_key = cipher_rsa.decrypt(enc_session_key)

    # Decrypt the data with the AES session key
    cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
    data = cipher_aes.decrypt_and_verify(ciphertext, tag)

    return data


这里调用send_data(),传入套接字、接收方的公钥以及他们想要发送的数据。

假设主机收到数据后调用decrypt_data(),并调用pickle.loads()来获取send_data()发送的列表。

谢谢!!

python cryptography rsa client-server pycryptodome
1个回答
0
投票

将会话密钥、标签和随机数发送给主机是正确的。我使用Python(和PyCryptodome)进行加密,但我不是专家。这就是我编写你的脚本的方式:

import os
import pickle
import struct
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.Random import get_random_bytes

PRIVATE_PATH = 'private_key.pem'

def send_data(socket, key, data):
    enc_session_key, nonce, tag, ciphertext = encrypt_data(key, data)
    encapsulated_data = [enc_session_key, nonce, tag, ciphertext]
    serialized_data = pickle.dumps(encapsulated_data)
    socket.sendall(struct.pack("<Q", len(serialized_data)) + serialized_data)

def encrypt_data(key, data, key_size=16):
    session_key = get_random_bytes(key_size)
    cipher_rsa = PKCS1_OAEP.new(key)
    enc_session_key = cipher_rsa.encrypt(session_key)
    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(data)

    return enc_session_key, cipher_aes.nonce, tag, ciphertext

def decrypt_data(enc_session_key, nonce, tag, ciphertext):
    try:
        private_key = RSA.import_key(open(PRIVATE_PATH).read())
        cipher_rsa = PKCS1_OAEP.new(private_key)
        session_key = cipher_rsa.decrypt(enc_session_key)
        cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce=nonce)
        data = cipher_aes.decrypt_and_verify(ciphertext, tag)
    
        return data
    except Exception as e:
        print(f"Decryption failed: {e}")
    return None
© www.soinside.com 2019 - 2024. All rights reserved.