【问题标题】:Python RSA key, recieved the key but getting error "This is not a private key"Python RSA 密钥,收到密钥但收到错误“这不是私钥”
【发布时间】: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


【解决方案1】:

嗯,是的,那是因为它是一个公钥

rsakey = RSA.import_key(rsa_public.decode())
cipher = PKCS1_OAEP.new(rsakey)
decrypted = cipher.decrypt(encyrpted)

根据定义,无法使用私钥进行加密。使用公钥进行加密,使用私钥进行解密。对于 RSA,公钥和私钥不可互换。也许您想生成一个签名?

使用私钥加密成功的唯一原因是它很可能还包含公共指数,因此也包含公钥。当然,公钥不包含私钥,因为私钥需要保密。

请注意,即使使用私钥加密是安全的如果两个密钥(以及模数)都保持私密,那么您也可以使用对称加密,例如使用模数上的哈希作为 AES 密钥。

【讨论】:

  • 哦,好吧,我去尝试切换键,这次它工作了。因为我试图在客户端和服务器之间建立一条隧道,服务器将向客户端发送信息的完整性安全级别,而一段时间后客户端将发送回消息的机密安全级别。是 RSA 的新手,所以不知道不允许使用私钥进行加密....感谢您的回答,我会尝试找出其他出路
  • 尝试 DH 密钥协议或使用公钥加密对称密钥。但是不要忘记进行身份验证(签名),否则您可能会允许中间人攻击。传输安全性很难,使用 TLS
猜你喜欢
  • 1970-01-01
  • 2011-03-20
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2013-07-15
相关资源
最近更新 更多