2016-05-13 63 views
0

我正在做一个小型的学校“项目”,这是一个小型的聊天程序。您启动服务器并且服务器将公钥发送到客户端,以便客户端可以发回加密的数据。从RSA解密中收到错误

问题是,当我试图在服务器端解密它时,我收到一个错误。

javax.crypto.BadPaddingException: Decryption error 
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380) 
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291) 

我的服务器等待一个socket.accept(),当一个客户端连接它发送一个公钥这个插座。

(这是不是整个代码)

private Client client; 
private JSONObject json; 

//Connector is used as a listener for messages. 
public Connector(Socket socket, ServerBroadCast SBC) throws IOException { 
    DIS = new DataInputStream(socket.getInputStream());   
    this.SBC = SBC; 
    this.client = SBC.AddClient(socket);   
    //Sending public RSA key to client to use to encrypt their message 
    this.client.sendPublicKey(RSA.getPublicKey()); //This is where I am sending RSA public key to client 
} 

我只是发送一条消息回服务器,看看它是否加密,如果服务器可以解密。

使用这个类发送到客户端

DataOutputStream DOS; 
public Client(Socket s) throws IOException { 
    DOS = new DataOutputStream(s.getOutputStream()); 
} 
public void sendPublicKey(PublicKey publicKey) throws IOException { 
    JSONObject json = new JSONObject(); 

    json.put(JSONKeys.TYPE, JSONTypes.PUBLIC_KEY); 
    json.put(JSONKeys.MESSAGE, RSA.getEncodedPublicKey()); 
    this.send(json); 
} 

public void send(JSONObject json) throws IOException{ 
    this.DOS.writeUTF(json.toString()); 
    System.out.println(json); 
} 

这里是我的RSA级加密和解密

private static PrivateKey privateKey = null; 
private static PublicKey publicKey = null; 

public static void generateKeyPair() { 
    KeyPairGenerator keyPairGenerator = null; 
    KeyPair keyPair = null; 

    try { 
     keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 

    keyPairGenerator.initialize(1024); 
    keyPair = keyPairGenerator.generateKeyPair(); 

    RSA.privateKey = keyPair.getPrivate(); 
    RSA.publicKey = keyPair.getPublic(); 
} 

public static String getEncodedPublicKey() { 
    return (new String(Base64.encode(RSA.getPublicKey().getEncoded()))); 
} 

public static String encrypt(String string) { 
    byte[] encrypted = null; 

    try { 
     Cipher cipher = Cipher.getInstance("RSA");//174 bytes 

     cipher.init(Cipher.ENCRYPT_MODE, RSA.getPublicKey()); 
     encrypted = cipher.doFinal(string.getBytes()); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } 

    return (new String(Base64.encode(encrypted))); 
} 

public static String decrypt(String string) { 
    byte[] decrypted = null; 

    try { 
     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 

     cipher.init(Cipher.DECRYPT_MODE, RSA.getPrivateKey()); 
     decrypted = cipher.doFinal(Base64.decode(string)); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } catch (Base64DecodingException e) { 
     e.printStackTrace(); 
    } 

    return (new String(decrypted)); 
} 

我得到的,有一些“错误”与因为我的填充错误说,但我不明白什么。

我从客户端加密消息得到的长度是174字节长。我已经知道它会很长,但为什么它会从我的纯文本中创建如此巨大的加密消息。

private final String MESSAGE = "Hello from client side"; 
+0

我唯一能想到的是JSON可能忽略了一些字节(不适合字符串)。尝试使用Base64对字节进行编码和解码。 (Java通过Base64.getEncoder()和Base64.get decoder()支持Base64)。 (发送密钥时,我的意思是) –

+0

@ Meguy26对不起,忘了添加另一个功能了。我已经使用Base64进行编码和解码。仍收到此错误 – Bojje

+0

发送密钥时怎么办? –

回答

1

看来,你有两个问题需要回答:

一)在客户端正确的公钥?

b)服务器上的密文是否正确?

尝试单独回答问题。例如,您可以尝试:

  1. 将服务器上的公钥加密并加密消息“hello world”。然后在服务器上取得私钥,并解密该消息。它有用吗?然后...

  2. 从#1中取出密文,并在客户端硬编码它,这样无论服务器发送给客户端的是什么,客户端都会将这个已知是正确的密文发回到服务器。现在,服务器是否再次解密?

如果服务器将其解密细,则可以:

  • 以从所述服务器的公共密钥并加密(在客户端上)的一些数据。现在,在客户端使用私钥解密数据。它解密了吗?

  • 好吧,现在把密文发送给服务器并解密。

  • 限制每一步未知数的数量。服务器能否真正解密正确的密文(可能不是由于某种错误)?客户能否真正收到正确的公钥?客户端能否发送正确的密文?

    +0

    谢谢..我做了你所说的,结果证明我没有正确处理接收公钥。 – Bojje