Reputation: 15
I imported a public key from java to python i am using sockets
in java i am using RSA/ECB/PKCS1Padding
and in python i am using the Crypto
library
in the variable server_public_key
i'm importing the public key
and in cipher
i use PKCS1_OAEP
to encrypt the message
in ciphertext
i encrypt the message
then i convert it to a bytearray
and then i sent it back to java
but java sends this error Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
here's my code
message = "SENDING TO JAVA"
s= socket.socket()
s.connect((address,9000))
data = s.recv(1024)
data = data[2:]
server_public_key = RSA.importKey(data)
cipher = PKCS1_OAEP.new(server_public_key)
ciphertext = cipher.encrypt(mensaje)
b = bytearray()
b.extend(ciphertext)
b = bytearray()
b.extend(ciphertext)
s.sendall(b)
Upvotes: 0
Views: 645
Reputation: 42009
When I remove the inexplicable second copy of the ciphertext being sent, and clean up and correct the python code, it works for me. Here is the python code I used.
import socket
import struct
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
#
# the following is an alternative recvall function that can be used
# if your platform does not provide the MSG_WAITALL socket flag.
#
def recvall2(s, size):
received_chunks = []
buf_size = 4096
remaining = size
while remaining > 0:
received = s.recv(min(remaining, buf_size))
if not received:
raise Exception('unexcepted EOF')
received_chunks.append(received)
remaining -= len(received)
return b''.join(received_chunks)
def recvall(s, size):
return s.recv(size, socket.MSG_WAITALL)
def oaep_example():
message = b"SENDING TO JAVA"
s = socket.socket()
s.connect(('127.0.0.1', 9000))
pubkey_size = struct.unpack(">H", recvall(s, 2))[0]
pubkey_der = recvall(s, pubkey_size)
server_public_key = RSA.importKey(pubkey_der)
cipher = PKCS1_OAEP.new(server_public_key)
cipher_text = cipher.encrypt(message)
s.sendall(cipher_text)
s.close()
if __name__ == '__main__':
oaep_example()
and the little Java server to demonstrate this is
import com.google.common.io.ByteStreams;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
public class Main {
public static void main(String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair rsaKeyPair = kpg.generateKeyPair();
ServerSocket serverSocket = new ServerSocket(9000);
Socket socket = serverSocket.accept();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
byte[] encodedPubKey = rsaKeyPair.getPublic().getEncoded();
dos.writeShort(encodedPubKey.length);
dos.write(encodedPubKey);
byte[] cipher = ByteStreams.toByteArray(socket.getInputStream());
socket.close();
Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
c.init(Cipher.DECRYPT_MODE, rsaKeyPair.getPrivate());
byte[] plain = c.doFinal(cipher);
System.out.println(new String(plain, StandardCharsets.UTF_8));
}
}
Note: ByteStreams
comes from the google Guava library.
Upvotes: 1