【发布时间】:2020-02-18 15:52:13
【问题描述】:
客户代码
import socket, json
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5
from Cryptodome.Random import get_random_bytes
from Cryptodome.PublicKey import RSA
def getnewsocket():
return socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket = getnewsocket()
clientsocket.connect(('localhost', 8089))
rsa_public = clientsocket.recv(99999)
encyrpted = clientsocket.recv(99999)
print(rsa_public)
rsakey = RSA.import_key(rsa_public.decode())
print(rsakey)
cipher = PKCS1_OAEP.new(rsakey)
decrypted = cipher.decrypt(encyrpted)
print(decrypted)
服务器代码
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5
from Cryptodome.Random import get_random_bytes
from Cryptodome.PublicKey import RSA
import socket
import json
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('0.0.0.0', 8089)) # 0.0.0.0 is a special address
print("Server activated, waiting for client to connect")
serversocket.listen(5)
connection, address = serversocket.accept()
rsakey_pair=RSA.generate(2048)
rsa_private = rsakey_pair
rsa_public = rsakey_pair.publickey().export_key()
hi = b"this is a plain text"
print(rsa_public)
cipher = PKCS1_OAEP.new(rsa_private)
encyrpted = cipher.encrypt(hi)
connection.sendall(rsa_public)
connection.sendall(encyrpted)
尝试了很多方法,但要么获取字节不能为 n,要么这不是私钥。始终无法在客户端解密密文内容。我猜这个错误是与socket相关的只能发送字节,所以当key通过socket发送时,虽然它仍然是字节但是是不同类型的字节
错误:
File "C:\Users\shang\AppData\Local\Programs\Python\Python37-32\lib\site-packages\Cryptodome\Cipher\PKCS1_OAEP.py", line 171, in decrypt
m_int = self._key._decrypt(ct_int)
File "C:\Users\shang\AppData\Local\Programs\Python\Python37-32\lib\site-packages\Cryptodome\PublicKey\RSA.py", line 151, in _decrypt
raise TypeError("This is not a private key")
TypeError: This is not a private key
【问题讨论】:
-
clientsocket.recv(99999)...recv()不是这样工作的,它很快就会咬你。recv(n)返回 最多 n 个字节,但如果可用的字节数较少,则它将与这些字节一起返回。在实践中,这意味着如果您的密钥被拆分为多个 TCP 数据包,那么在您开始尝试使用它之前,您不会收到所有密钥。 -
所以我必须始终知道我发送的内容的字节并为此设置一个值?还有其他方法吗?
-
你必须总是有某种方式知道你什么时候结束了
recving。如果您只是发送/接收一件不太大的事物,那么最简单的解决方案是在套接字上recv(),直到对等方完成发送并关闭套接字。这大致相当于在文件 EOF 之前读取。如果那个“一件事”是一个 JSON 对象,那么您可以将其全部读入,将其传递给json模块的方法,并相对容易地解析出不同的字段。 -
在带有阻塞套接字的 python 中读取直到套接字结束(即 EOF)相对容易。
socket.recv(n)将阻塞,直到有一些数据可以提供给您,或者连接关闭。连接关闭返回时,返回值为空字节对象b""。对此here有一些讨论。
标签: python-3.x cryptography rsa