【问题标题】:CipherInputStream is Empty when trying to decrypt file尝试解密文件时 CipherInputStream 为空
【发布时间】:2014-05-07 12:10:05
【问题描述】:

我正在尝试编写一些辅助方法来处理加密文件的读写。我有两种方法可以成功实现这一点并返回一个 InputStream 或一个 OutputStream (它们实际上是 Cipher 版本),我可以使用它们来读取或写入文件。我已经确认这些方法在使用对象流包装并用于读取和写入加密对象到文件时非常有效。

但是,当我尝试从加密的文本文件中读取时,就会出现问题。我可以验证我提供给它的字符串是否被加密并写入正确的文件,但是当我尝试从这个文件中读回时,BufferedReader 报告一个 EOF (null)。 InputStream.available() 方法返回 0。我可以确保文件在那里,正在被找到,并且 InputStream 本身不为空。谁能告诉我这是什么原因造成的?

读/写加密对象效果很好(CorruptedStreamException 在这里很好):

        private static void testWriteObject() {
    String path = "derp.derp";
    Derp start = new Derp("Asymmetril: " + message, 12543, 21.4, false);
    FilesEnDe.writeEncryptedObject(key, "derp.derp", start);
    echo("original");
    echo(">"+start);

    Object o;
    try {
        ObjectInputStream ois = new ObjectInputStream(ResourceManager.getResourceStatic(path));
        o = ois.readObject();
        echo("encrypted");
        echo(">"+o);
        ois.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

    o = FilesEnDe.readEncryptedObject(key, path);
    echo("decrypted");
    echo(">"+o);
}

输出:

original
>Asymmetril: WE CAME, WE SAW, WE CONQUERED.; 12543; 21.4; false
[RM] > Trying to load resource: derp.derp
java.io.StreamCorruptedException
[RM] > Trying to load resource: derp.derp
decrypted
>Asymmetril: WE CAME, WE SAW, WE CONQUERED.; 12543; 21.4; false

尝试解密文本文件不行(注意加密后的文本是可读的):

private static void testWriteFile() {
    String path = "EncryptedOut.txt";
    BufferedReader bis1, bis2;

    try {
        BufferedOutputStream os = new BufferedOutputStream(FilesEnDe.getEncryptedOutputStream(key, path));
        os.write(message.getBytes());
        os.flush();
                    os.close();
    } catch (IOException e1) {
        e1.printStackTrace();
    }

    echo("original");
    echo(">"+message);

    try {
        bis1 = new BufferedReader (new InputStreamReader(ResourceManager.getResourceStatic(path)));
        echo("encrypted");
        echo(">" + bis1.readLine());
        bis1.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        InputStream is = FilesEnDe.getEncryptedInputStream(key, path);
        InputStreamReader isr = new InputStreamReader(is);
        bis2 = new BufferedReader (isr);
        echo("bits in stream? " + is.available());

        echo("decrypted");
        echo(">"+bis2.readLine());
        bis2.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    }

输出:

original
>WE CAME, WE SAW, WE CONQUERED.
encrypted
>¤ƒ]£¬Vß4E?´?ùûe
[RM] > Trying to load resource: EncryptedOut.txt
bytes in stream? 0
decrypted
>null

用于创建 CipherInputStream 的代码:

    public static InputStream getEncryptedInputStream(String key, String path) {
    try {
        InputStream is = ResourceManager.getResourceStatic(path);
        SecretKeySpec keyspec = new SecretKeySpec(getHash(key),"AES");
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, keyspec);
        return new CipherInputStream(is,c);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    }
    return null;
    }

当我尝试使用密码输入流解密文件并检索原始字符串时出现问题。

【问题讨论】:

    标签: java inputstream bufferedreader


    【解决方案1】:

    但是,当我尝试从加密的文本文件中读取时,就会出现问题。

    没有“加密文本文件”之类的东西。加密的结果是二进制,而不是文本。

    我可以验证我提供给它的字符串是否被加密并写入正确的文件,但是当我尝试从这个文件中读回时,BufferedReader 报告一个 EOF (null)。

    你不应该使用BufferedReader. 它不是文本,它是二进制的。使用BufferedInputStream.

    【讨论】:

    • 请注意,我可以很好地阅读加密文本。它看起来像垃圾,因为你是对的。我强制将该二进制文件作为文本读取,它会产生很多乱码。问题是,当我从文件创建 CipherInputStream 时,我无法从中提取任何内容,无论是否缓冲,无论是否为二进制。不过,感谢您的尝试。
    • 您的问题是“谁能告诉我这可能是什么原因?”指的是BufferedReader,,它也是您标题的第一个单词。我已经回答过了。你还有一个吗?
    • 您的文件因使用PrintWriter 而损坏 - 它以文本(如字符代码)形式而不是原始数据威胁传出数据,并根据您的平台编码应用一些过滤器。使用严格的输入/输出(不是作家、读者),一切都会好起来的。
    • 我已将标题更改为更合适的名称,现在将尝试更换打印机。
    • 我已将 PrintWriter 替换为 BufferedOutputStream 并改为写入消息的字节。我已经更新了上面的代码以反映这一点。不过,问题仍然存在。无论我是通过 PrintWriter 还是 BufferedOutputStream 填充文件,文件的 CipherInputStream 仍然是空的。我误解你的意思了吗?
    【解决方案2】:

    无论我是通过 PrintWriter 还是 BufferedOutputStream 编写,也不管我是否使用 Reader 阅读。原来,我忘了关闭创建文件的 OutputStream。一旦我添加了那条小线,一切就开始工作了。感谢 Antoniossss 建议我重做方法中损坏的部分。我想知道为什么 Eclipse 没有提到它的资源泄漏......

    【讨论】:

    • 这很重要。对二进制数据使用 Writer 或 Reader 是不正确的。
    • 您说得对,先生。但是,如果您真的阅读了我的问题,您会注意到我使用 writer 将 String 写入 Stream。加密发生在之后。后来,在解密已经发生后,我使用阅读器从流中读取字符串。我不是说你错了,但你解决了错误的问题,我不喜欢仅仅因为沟通不畅而被否决。
    • 变量 message 是一个字符串,请注意它在输出中的打印效果有多好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多