javax.crypto.BadPaddingException:给定的最终块未正确填充-DES解密

javax.crypto.BadPaddingException:给定的最终块未正确填充-DES解密,java,cryptography,Java,Cryptography,我正在尝试解密服务器上的消息-我得到的错误是 使用的加密技术-DES --线程“main”javax.crypto.BadPaddingException中的异常:给定的最后一个块没有正确填充 我很难解决这个问题, 任何帮助都将不胜感激 class TCPClient { public static void main(String argv[]) throws Exception { byte[] sentence, textEncrypted; String modified

我正在尝试解密服务器上的消息-我得到的错误是

使用的加密技术-DES

--线程“main”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();
}
}

执行此操作将丢失数据:

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

除此之外,没有必要。密文不是现代密码的真正文本,它是二进制的。由于套接字提供二进制
InputStream
s和
OutputStream
s,因此也没有理由将密文转换为字符串。所需的只是将可能的输入字符串转换为二进制(当然,在客户端和服务器上使用相同的编码,现在首选UTF-8)。

这里只是头脑风暴,但您的客户端salt与服务器端salt不同。这不会导致任何问题吗?我确实尝试过使用盐,但最终还是出现了相同的错误:(在修改后的代码中,我写的是字节,而不是通过TCP发送字符串。我面临的唯一问题是在服务器上导出密钥,请建议我如何在系统之间共享密钥。在这种情况下,您可能希望共享包含密钥的二进制文件。我的意思是,其中没有任何内容是安全的,因此我假定这是正确的。)正在测试.SecretKey.getEncoded(),KeyFactory…但这是另一个问题。为了安全起见,请使用TLS和PKI方案。