2016-05-13 61 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