2017-03-15 1 views
0

나는 서버에 메시지를 해독하기 위해 노력하고 있어요 - 내가 가진 어떤 오류가 사용javax.crypto.BadPaddingException : 최종 블록 제대로 패딩되지 않는 감안할 때 - DES지고 복호화

암호화 기술이다 - DES.

스레드에서

--Exception "주요"javax.crypto.BadPaddingException : 감안할 때 마지막 블록이 제대로

나는이 문제를 해결하기 위해 노력하고 매우 어려운 시간을 보내고 있어요 패딩하지 도움이 될 것입니다 알

class TCPClient { 
public static void main(String argv[]) throws Exception { 
    byte[] sentence, textEncrypted; 
    String modifiedSentence; 
    String password; 
    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); 
    Socket clientSocket = new Socket("localhost", 6789); 
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); 
    password = "Passcode"; 
    byte[] salt = new byte[64]; 
    Random rnd = new Random(); 
    rnd.nextBytes(salt); 
    byte[] data = deriveKey(password, salt, 64); 

    // BufferedReader inFromServer = new BufferedReader(new 
    // InputStreamReader(clientSocket.getInputStream())); 
    System.out.println("Enter the Data to be transmisted to server\n"); 
    sentence = inFromUser.readLine().getBytes(); 
    SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data)); 
    Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, desKey); 
    textEncrypted = cipher.doFinal(sentence); 
    outToServer.writeBytes(new String(textEncrypted) + '\n'); 
    clientSocket.close(); 
} 

public static byte[] deriveKey(String password, byte[] salt, int keyLen) { 
    SecretKeyFactory kf = null; 
    try { 
     kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen); 
    SecretKey key = null; 
    try { 
     key = kf.generateSecret(specs); 
    } catch (InvalidKeySpecException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return key.getEncoded(); 
} 
} 

서버 측 코드

class TCPServer { 
public static void main(String argv[]) throws Exception { 
    String password = null; 
    String capitalizedSentence; 
    ServerSocket welcomeSocket = new ServerSocket(6789); 

    while (true) { 
     Socket connectionSocket = welcomeSocket.accept(); 
     BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); 
     password = "Passcode"; 
     byte[] salt = new byte[64]; 
     Random rnd = new Random(); 
     rnd.nextBytes(salt); 
     byte[] data = deriveKey(password, salt, 64); 
     byte [] EncyptedText = inFromClient.readLine().getBytes(); 
     System.out.println("Received Encrypted message " + EncyptedText); 
     SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data)); 
     Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, desKey); 
     // Decrypt the text 
     System.out.println("Text Received " + EncyptedText); 
     byte[] textDecrypted = cipher.doFinal(EncyptedText); 
     System.out.println("Text Decryted : " + new String(textDecrypted)); 

    } 
} 

public static byte[] deriveKey(String password, byte[] salt, int keyLen) { 
     SecretKeyFactory kf = null; 
     try { 
      kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen); 
     SecretKey key = null; 
     try { 
      key = kf.generateSecret(specs); 
     } catch (InvalidKeySpecException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return key.getEncoded(); 
} 
} 
+0

여기에 브레인 스토밍하지만 클라이언트 측 소금은 서버 측 것과 다릅니다. 그게 문제가되지 않을까요? –

+0

나는 소금을 사용하여 시도했지만 같은 오류가 끝납니다 : ( –

답변

0

이 작업을 수행하는 데이터가 손실됩니다.

outToServer.writeBytes(new String(textEncrypted) + '\n'); 

그 외에도 필요하지 않습니다. 암호문은 현대 암호에 대한 텍스트가 아니라 바이너리입니다. 소켓이 바이너리 InputStreamOutputStream을 제공하므로 암호문을 문자열로 변환 할 이유가 없습니다. 가능한 모든 입력 문자열을 바이너리로 변환하는 것이 필요합니다 (물론 클라이언트와 서버 모두 동일한 인코딩을 사용합니다 - 요즘 UTF-8이 선호됩니다).

+0

수정 된 코드에서 대신 TCP를 통해 문자열을 보내는 바이트 쓰고 있어요. 내가 겪고있는 유일한 문제는 서버에서 비밀 키를 파생시키는, 제발 방법을 제안하십시오 어떻게하면 시스템간에 키를 공유 할 수 있습니까? –

+0

이 경우에는 키가 들어있는 바이너리 파일을 공유하고 싶습니다. 어쨌든 보안에 문제가 없으므로 테스트하는 것으로 추정됩니다 .SecurityKey.getEncoded(), KeyFactory ...하지만 그것은 또 다른 문제입니다. TLS와 PKI 체계를 사용하여 보안을 유지하십시오. –