0

code for cilent

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)

code for server

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)

tried alot of ways but is either getting bytes cannot be n or this is not a private key. Always unable to decrypt the content of ciper text at client. I guess the error is something related to socket only can send bytes, so when the key had send through the socket, although it is still in bytes but is a different kind of bytes

error :

  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
4
  • clientsocket.recv(99999) ... that's not how recv() works, and it will bite you very soon. recv(n) returns at most n bytes, but if there are fewer available then it will return with those. In practice, that means that if your keys are split across multiple TCP packets then you won't have received all of it before you start trying to use it. Commented Feb 19, 2020 at 4:31
  • so i must always know the bytes of the content Im sending and set a value for that? any alternative ways of doing this? Commented Feb 19, 2020 at 16:23
  • You must always have some way of knowing when you've gotten to the end of whatever you're recving. If you are just sending/receiving one thing that's not too large, then the simplest solution is to recv() on the socket until the peer finishes sending and closes the socket. That is roughly equivalent to reading until EOF on file. And if that "one thing" is a JSON object, then you can read it all in, pass it to the methods of the json module and relatively easily parse out different fields. Commented Feb 19, 2020 at 18:07
  • Reading until end-of-socket (i.e. EOF) is relatively easy in python with blocking sockets. socket.recv(n) will block until there is some data to give you, or the connection is closed. When it returns because of connection closure, the returned value is the empty bytes object b"". There is some discussion of this here. Commented Feb 19, 2020 at 18:09

1 Answer 1

3

Well, yes, that's because it is a public key.

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

It is not possible to encrypt with a private key by definition. Encryption is performed using the public key, decryption using the private key. Public and private keys are not interchangeable for RSA. Maybe you want to generate a signature instead?

The only reason why the encryption with the private key succeeds is that it is likely that it also contains the public exponent and therefore the public key. Of course, the public key doesn't contain the private key as that needs to be kept private.

Note that even if it would be secure to encrypt with a private key if both keys (and thus the modulus) are kept private then you might as well use symmetric encryption, e.g. using the hash over the modulus as AES key.

Sign up to request clarification or add additional context in comments.

2 Comments

ohhh okay, I went to tried switching the key around and this time it work. Because i was trying to make a tunnel between client and server that server will send integrity security level of information to client, while after awhile client will send back a confidential security level of message. Was new to RSA so didnt know that private key is not allowed to use to encrypt.... thanks for your answer, i will try to figure other way out then
Try DH key agreement or encryption of a symmetric key with the public key. But don't forget to authenticate (sign) because otherwise you may allow a man-in-the-middle attack. Transport security is hard, use TLS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.