CipherOutputStream 不工作。没有东西被写入 OutputStream。

huangapple go评论74阅读模式
英文:

CipherOutputStream not working. Nothing gets written into OutputStream

问题

我正在创建一个网络系统,一切都正常,除了加密。我正在使用CipherOutputStream和CipherInputStream。所以我开始调试...所以我创建了一个单独的应用程序,用于生成AES加密密钥,并在Cipher中使用它。 代码如下:

    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    keyGenerator.init(128);
    SecretKey secretKey = keyGenerator.generateKey();
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    CipherOutputStream cipherOutputStream = new CipherOutputStream(new OutputStream() {
        @Override
        public void write(int b) throws IOException {
            System.out.println("Test");
            System.out.print((char) b);
        }
    }, cipher);
    cipherOutputStream.write('c');

什么都没有打印到控制台。有谁知道问题出在哪里?

英文:

I'm creating a network system, everything works fine, except encryption. I'm using CipherOutputStream and CipherInputStream. So I've started debugging... so I created a separate application that generates AES encryption key and uses it in Cipher. The code:

    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    keyGenerator.init(128);
    SecretKey secretKey = keyGenerator.generateKey();
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    CipherOutputStream cipherOutputStream = new CipherOutputStream(new OutputStream() {
        @Override
        public void write(int b) throws IOException {
            System.out.println("Test");
            System.out.print(((char) b));
        }
    }, cipher);
    cipherOutputStream.write('c');

Nothing get's printed into the console. Does anyone know where is the problem?

答案1

得分: 2

你正在使用ECB模式,这是标准/开放JDK的默认模式。因此,"AES"会被转换为"AES/ECB/PKCS5Padding"。现在,ECB在加密/解密过程中需要完整的数据块作为输入。只有消息的最后一部分可能不是完整的数据块:在使用PKCS#7标准(PKCS#5是相同的标准)进行加密之前,它会进行填充。

很好,所以发生的情况是,你写入了一个单个字节。这个字节显然不是一个完整的数据块。因此,密码流将等待更多字节进来以形成一个完整的数据块。如果它被关闭或者会对剩余的字节进行填充,并将它们放入连接的输出流中。只要不关闭流,就不会写入任何内容。

我建议使用try-with-resources来解决这个问题。并且请至少使用一个内部类或类似的方式来定义它,而不是在同一行上定义它。

英文:

You are using ECB mode, which is the default for the standard / open JDK. So "AES" gets translated to "AES/ECB/PKCS5Padding". Now ECB requires full blocks as input during encryption / decryption. Only the last part of the message may not be a complete block: it gets padded before encryption using PKCS#7 standard (PKCS#5 is the same thing).

Great, so what happens is that you write a single byte. This byte is obviously not a complete block. So the cipherstream is going to wait for more bytes to come in to form a complete block. If it gets closed or it will pad the remaining bytes and put them to the connected output stream. As long as you don't close the stream however, nothing gets written.

I'd use try-with-resources to get around this issue. And please use at least an inner class or something like that instead of defining it on the same line.

huangapple
  • 本文由 发表于 2020年7月31日 03:41:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63180256.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定