Java 如何减少从服务器接收的字符串?

Java 如何减少从服务器接收的字符串?,java,string,sockets,encryption,Java,String,Sockets,Encryption,我正在创建一个带有加密的echo服务器/客户端。基本上,我想让这个程序做的是: 用户在客户端中键入一个字符串 客户端对字符串进行加密 客户端将加密字符串发送到服务器 服务器接收字符串 服务器将字符串发送回客户端 客户端接收字符串 客户端解密字符串 客户端显示解密的字符串 我的问题是,当客户端尝试解密从服务器接收的字符串时,它失败并抛出以下错误: Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input len

我正在创建一个带有加密的echo服务器/客户端。基本上,我想让这个程序做的是:

  • 用户在客户端中键入一个字符串
  • 客户端对字符串进行加密
  • 客户端将加密字符串发送到服务器
  • 服务器接收字符串
  • 服务器将字符串发送回客户端
  • 客户端接收字符串
  • 客户端解密字符串
  • 客户端显示解密的字符串
  • 我的问题是,当客户端尝试解密从服务器接收的字符串时,它失败并抛出以下错误:

    Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length
    must be multiple of 8 when decrypting with padded cipher
            at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:936)
            at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
            at java.base/com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)
            at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
            at EnClient.decrypt(EnClient.java:100)
            at EnClient.main(EnClient.java:85)
    
    在将字符串发送到服务器之前,我已经尝试过对其进行解密,然后它工作得很好,所以这肯定与字符串通过套接字发送到服务器并返回有关。我还注意到,当加密字符串的填充出现某种问题时,通常会出现错误。除了这些信息之外,我还不知道该怎么做,也不知道如何解决这个问题。所以我需要你的帮助。首先,请告诉我我的假设是否正确,以及你对如何解决这个问题的建议

    客户端代码:

    
    c1=Cipher.getInstance(“DES”);
    字符串用户输入;
    而((userInput=stdIn.readLine())!=null){
    字节[]eui=加密(用户输入);
    系统输出打印项次(eui);
    System.out.println(解密(eui));
    out.println(eui.toString());
    byte[]ein=in.readLine().getBytes();
    字符串din=解密(ein);
    系统输出打印号(din);
    }
    ...
    私有静态字符串解密(字节[]encryptionBytes)引发异常{
    c1.init(Cipher.DECRYPT_模式,k);
    字节[]recoveredBytes=c1.doFinal(encryptionBytes);
    恢复的字符串=新字符串(恢复的字节);
    回收的收益;
    }
    私有静态字节[]加密(字符串输入)引发异常{
    c1.init(Cipher.ENCRYPT_模式,k);
    byte[]ib=input.getBytes();
    返回c1.doFinal(ib);
    }
    
    服务器代码:

    字符串输入行;
    而((inputLine=in.readLine())!=null){
    out.println(inputLine);
    }
    
    我想我可以通过比较接收到的字符串和原始加密字符串来解决这个问题,如果它们匹配,那么就解密原始字符串,但这看起来像是一个程序,只需要额外的步骤来加密和解密字符串,我不希望这样。我希望客户端对直接从服务器接收的字符串进行解密

    无论如何,任何帮助都将受到感谢

    编辑:

    我替换了这个:

    。。。
    字节[]eui=加密(用户输入);
    系统输出打印项次(eui);
    System.out.println(解密(eui));
    out.println(eui.toString());
    byte[]ein=in.readLine().getBytes();
    字符串din=解密(ein);
    系统输出打印号(din);
    ...
    
    为此:

    。。。
    字节[]eui=加密(用户输入);
    字符串b64eui=Base64.getEncoder().encodeToString(eui);
    out.println(b64eui);
    字节[]ein=Base64.getDecoder().decode(in.readLine().getBytes());
    字符串din=解密(ein);
    System.out.println(“echo:+din”);
    ...
    
    输出。println
    追加换行符(
    \n

    可能这会导致加密的字节数组的长度错误。

    eui.toString()
    不会做您认为它会做的事情。它没有任何用处。此外,您还混合了面向字节和面向字符的IO。对于初学者来说,这可能非常复杂。我认为最简单的解决方案是继续使用面向字符的IO,但在通过套接字发送之前,使用Base64类将
    字节[]
    编码为字符串。请记住在解密之前将字符串解码回
    字节[]
    readLine()
    将删除
    println()
    添加的换行符。