【问题标题】:CipherOutputStream not working. Nothing gets written into OutputStreamCipherOutputStream 不工作。没有任何内容被写入 OutputStream
【发布时间】:2020-08-03 12:00:18
【问题描述】:

我正在创建一个网络系统,一切正常,除了加密。我正在使用 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');

没有任何东西被打印到控制台中。有谁知道问题出在哪里?

【问题讨论】:

  • 您正在使用分组密码的分组模式,在本例中为 AES。在您写入至少 16 个字节之前,它无法执行任何操作。在此之前,数据被缓冲。
  • @Presidenr James K. Polik 抱歉,我对这个有点陌生,所以在将新字节 [16] 写入 CipherOutputStream 之后,一切都应该正常工作吗?
  • 我不知道“一切”是什么。
  • 这里的根本问题是您忘记关闭密码输出流。

标签: java cryptography


【解决方案1】:

您正在使用 ECB 模式,这是标准/开放 JDK 的默认设置。所以"AES" 被翻译成"AES/ECB/PKCS5Padding"。现在 ECB 在加密/解密期间需要完整的块作为输入。只有消息的最后一部分可能不是一个完整的块:它在使用 PKCS#7 标准加密之前被填充(PKCS#5 是一样的)。

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

我会使用try-with-resources 来解决这个问题。请至少使用一个内部类或类似的东西,而不是在同一行定义它。

【讨论】:

    猜你喜欢
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多