我的三个问题如下:
我无法弄清楚如何填充字节并让它在没有错误的情况下工作:javax.crypto.BadPaddingException: Given final block not properly padded
如果我将其切换为NoPadding,我必须使用8的倍数的字符串
最后也是最重要的是,我无法让服务器正确解密它。我在 CipherClient.java 中证明解密在通过套接字发送之前有效。
使用asHex,我可以证明CipherServer.java获取相同的字节,但在解密消息时,它无法正确解密。
我错过了什么吗?我不明白客户端如何正确解密它,但一旦通过流,服务器就不能。
我一整天都在寻找互联网上的例子,我无法弄明白。 在有人说出某些内容之前,我知道DES并不明智,但是,这只适用于需要DES的项目。
CIPHERCLIENT.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();
}
}
}
CIPHERSERVER.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();
}
}
答案 0 :(得分:1)
在创建密钥文件之前,您可以在服务器上创建套接字,并且服务器正确地从上次运行中读取密钥。
在关闭密钥文件后尝试将Socket s = new Socket(host, port);
移至。
事件如下:
Client Server
----------------- ------------------
Connect to server
Accept connection
Read key file
(block on receive)
Generate Key
Write Key File
Send message
Receive message
etc.
答案 1 :(得分:0)
查看代码我只能假设密钥不正确。也许您使用的是错误的文件夹或类似文件夹。 BadPaddingException
通常仅在填充不正确,数据的最后一个块已损坏或您使用了错误的密钥时才会出现。也许您可以使用调试器或SecretKey.getEncoded()
来检查密钥是否与十六进制编码器一起使用。