javax.crypto.BadPaddingException:给定的最终块未正确填充-DES解密
我正在尝试解密服务器上的消息-我得到的错误是 使用的加密技术-DES --线程“main”javax.crypto.BadPaddingException中的异常:给定的最后一个块没有正确填充 我很难解决这个问题, 任何帮助都将不胜感激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
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方案。