RSA Python加密来自导入的Java公钥的消息

时间:2017-08-17 17:02:24

标签: java python sockets encryption rsa

我从java导入了一个公钥到python我正在使用套接字

在java中我正在使用RSA/ECB/PKCS1Padding

在python中我正在使用Crypto

变量server_public_key中的

我正在导入公钥

并在cipher我使用PKCS1_OAEP来加密消息

ciphertext中的

我加密消息

然后我将其转换为bytearray

然后我把它发回给java

但java发送此错误Exception in thread "main" javax.crypto.BadPaddingException: Decryption error

这是我的代码

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)      

1 个答案:

答案 0 :(得分:0)

当我删除正在发送的密文的无法解释的第二个副本,并清理并更正python代码时,它对我有用。这是我使用的python代码。

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()

和小Java服务器来证明这一点

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));
    }
}

注意:ByteStreams来自Google Guava库。