给定最终块没有正确填充异常

时间:2018-04-11 14:00:55

标签: java encryption

我有服务器 - 客户端套接字从客户端向服务器发送字节数组,我正在尝试使用密码输入流,密码输出流但是我得到以下异常:

  

javax.crypto.BadPaddingException:给定最终块不正确   填充。线程“main”java.io.IOException中的异常:   javax.crypto.BadPaddingException:给定最终块不正确   填补   javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:121)at at   javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:121)     在javax.crypto.CipherInputStream.read(CipherInputStream.java:239)     在javax.crypto.CipherInputStream.read(CipherInputStream.java:215)     在SecretSocketServer.main(SecretSocketServer.java:46)引起:   javax.crypto.BadPaddingException:给定最终块不正确   填补   com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)at at   com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)at at   com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)     在javax.crypto.Cipher.doFinal(Cipher.java:2048)at   javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:118)

我尝试了与“DES”不同的算法,但仍然得到相同的异常 这是我的代码:

public class SecretSocket {
    Cipher inCipher, outCipher;
    Socket socket;
    Key key;

    public SecretSocket(Socket socket, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        this.key = key;
        this.socket = socket;
        initializeCipher();
    }

    private void initializeCipher() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        outCipher = Cipher.getInstance("DES");
        outCipher.init(Cipher.ENCRYPT_MODE, key);
        inCipher = Cipher.getInstance("DES");
        inCipher.init(Cipher.DECRYPT_MODE, key);

    }

    public InputStream getInputStream() throws IOException {
        InputStream is = socket.getInputStream();
        CipherInputStream cis = new CipherInputStream(is, inCipher);
        return cis;
    }

    public OutputStream getOutputStream() throws IOException {
        OutputStream os = socket.getOutputStream();
        CipherOutputStream cos = new CipherOutputStream(os, outCipher);
        return cos;
    }
}
public class KeyGen {
    public static void writeKey() throws NoSuchAlgorithmException, FileNotFoundException, IOException {
        KeyGenerator kg = KeyGenerator.getInstance("DES");
        Key key = kg.generateKey();
        File file = new File("key1.txt");
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(key);
    }
public class SecretSocketServer {
    public static void main(String[] args) throws IOException, FileNotFoundException, ClassNotFoundException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        int port = 12345;
        ServerSocket Serversocket;
        Socket clientSocket;
        Serversocket = new ServerSocket(port);
        System.out.println("Waiting for client to connect");
        clientSocket = Serversocket.accept();
        System.out.println("New Client Connected");
        Key key = KeyGen.getSecretKey();
        System.out.println("The Key is: " + key);

        SecretSocket s = new SecretSocket(clientSocket, key);
        InputStream in = s.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] b = new byte[1024];
        int numberOfBytedRead;

        while ((numberOfBytedRead = in.read(b)) >= 0) {
            baos.write(b, 0, numberOfBytedRead);
        }

        System.out.println(new String(baos.toByteArray()));
        Serversocket.close();
    }
}

public static final String KEY_FILE = "key1.txt";
public static Key getSecretKey() throws FileNotFoundException, IOException, ClassNotFoundException {
    FileInputStream fis = new FileInputStream(KEY_FILE);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Key key = (Key) ois.readObject();
    return key;
}
public class SecretSocketClient {
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, ClassNotFoundException, NoSuchPaddingException, InvalidKeyException {
        int port = 12345;
        Socket soc = new Socket("localhost", port);
        System.out.println("Connected to server");
        KeyGen.writeKey();
        Key key = KeyGen.getSecretKey();
        System.out.println("Key Generated: " + key);
        SecretSocket s = new SecretSocket(soc, key);
        //InputStream in = s.getInputStream();
        OutputStream out = s.getOutputStream();
        out.write("HELLOWORLD".getBytes());
        out.flush();
        out.close();
        soc.close();
        System.out.println("The MSG has been sent");
    }
}

1 个答案:

答案 0 :(得分:1)

有很多事情可能会导致“填充不良”异常。基本上任何导致最后一个块结束不匹配预期填充的东西都会引发错误。可能的原因包括:填充设置不正确,密钥错误,密文错误等。

要尝试诊断问题,请将解密端设置为NoPadding。这将接受任何内容,并允许您检查输出:

  • 完全垃圾:您可能在密钥或错误的模式设置中出错。

  • 第一次阻止垃圾:您可能遇到密钥错误或IV错误。

  • 最后一个块垃圾:可能是cyphertext文件的损坏结束。

  • 正确的解密,最后有一些奇怪的字节:奇怪的字节是填充。

如果它只是填充,那么设置解密函数以期望这种填充。否则,检查加密和解密的密钥/ IV / cyphertext byte-to-byte 是否相同。

至关重要您在诊断后设置了填充模式。 NoPadding是不安全的。