我的三个问题如下:
我不知道如何填充字节并让它在没有错误的情况下工作:
javax.crypto.BadPaddingException: Given final block not properly padded
如果我将它切换到 NoPadding,我必须使用一个 8 的倍数的字符串
最后也是最重要的是,我无法让服务器正确解密它。我在CipherClient.java中证明解密在通过套接字发送之前有效。
使用 asHex,我可以证明 CipherServer.java 获得了相同的字节,但是在解密消息时,它没有正确解密。
我错过了什么吗?我不明白客户端如何正确解密它,但是一旦通过流,服务器就不能。
我整天都在互联网上寻找示例,但我无法弄清楚。在有人说什么之前,我知道使用 DES 并不明智,但是,这仅适用于需要 DES 的项目。
密码客户端.java
import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
public class CipherClient
{public static void main(String[] args) throws Exception
{
try {
//Starts socket
String host = "localhost";
int port = 8001;
Socket s = new Socket(host, port);
//Generate a DES key.
KeyGenerator keygen = KeyGenerator.getInstance("DES");
keygen.init(56, new SecureRandom());
SecretKey key = keygen.generateKey();
//Store the key in a file
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
oos.writeObject(key);
oos.close();
//Start Cipher Instance and cipher the message
//Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
Cipher c = Cipher.getInstance("DES/ECB/NoPadding");
c.init(Cipher.ENCRYPT_MODE,key);
//Get string and encrypted version
//String message = "The quick brown fox jumps over the lazy dog.";
String message = "12345678";
byte[] encryptedMsg = c.doFinal(message.getBytes("UTF-8"));
System.out.println("Client - Message: " + message);
System.out.println("Client - Encrypted: " + CipherServer.asHex(encryptedMsg));
//TEST DECRYPT W/ KEY FILE W/O SERVER (WORKS!)
//-------------------------------
//Read key from file test
ObjectInputStream file = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
SecretKey key2 = (SecretKey) file.readObject();
System.out.println("Key Used: " + file.toString());
file.close();
//Decrypt Test
c.init(Cipher.DECRYPT_MODE,key2);
byte[] plainText = c.doFinal(encryptedMsg);
System.out.println("Decrypted Message: " + new String(plainText));
//Open stream to cipher server
DataOutputStream os = new DataOutputStream(s.getOutputStream());
os.writeInt(encryptedMsg.length);
os.write(encryptedMsg);
os.flush();
os.close();
//Close socket
s.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
密码服务器.java
import java.io.*;
import java.net.*;
import java.security.NoSuchAlgorithmException;
import javax.crypto.*;
public class CipherServer
{
public static void main(String[] args) throws Exception
{
//Start socket server
int port = 8001;
ServerSocket s = new ServerSocket();
s.setReuseAddress(true);
s.bind(new InetSocketAddress(port));
Socket client = s.accept();
CipherServer server = new CipherServer();
server.decryptMessage(client.getInputStream());
s.close();
}
public void decryptMessage(InputStream inStream) throws IOException, NoSuchAlgorithmException
{
try {
//Create the Data input stream from the socket
DataInputStream in = new DataInputStream(inStream);
//Get the key
ObjectInputStream file = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
SecretKey key = (SecretKey) file.readObject();
System.out.println("Key Used: " + file.toString());
file.close();
//Initiate the cipher
//Cipher d = Cipher.getInstance("DES/ECB/PKCS5Padding");
Cipher d = Cipher.getInstance("DES/ECB/NoPadding");
d.init(Cipher.DECRYPT_MODE,key);
int len = in.readInt();
byte[] encryptedMsg = new byte[len];
in.readFully(encryptedMsg);
System.out.println("Server - Msg Length: " + len);
System.out.println("Server - Encrypted: " + asHex(encryptedMsg));
//String demsg = new String(d.doFinal(encryptedMsg), "UTF-8");
//System.out.println("Decrypted Message: " + demsg);
// -Print out the decrypt String to see if it matches the orignal message.
byte[] plainText = d.doFinal(encryptedMsg);
System.out.println("Decrypted Message: " + new String(plainText, "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
//Function to make the bytes printable (hex format)
public static String asHex(byte buf[]) {
StringBuilder strbuf = new StringBuilder(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
}