有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我使用socket将一个公钥从java导入python

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

在python中,我使用的是Crypto

在变量server_public_key中,我导入公钥

cipher中,我使用PKCS1_OAEP对消息进行加密

ciphertext中,我对消息进行加密

然后我把它转换成字节数组

然后我把它送回了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) 个答案

  1. # 1 楼答案

    当我删除正在发送的密文的第二个副本,并清理和更正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));
        }
    }
    

    注:^{}来自谷歌Guava