2

我目前正在尝试安全读取,加密然后同时加密同一个文件(出于安全原因)。我在下面编写的代码几乎实现了这一点,但在解密文件中添加了额外的字节。除了 c.init 在 DECRYPT_MODE 中之外,解密方法几乎完全相同。

    public static void encryptFile(String path, byte[] key) throws Exception {

    Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
    SecretKeySpec k = new SecretKeySpec(key, "AES");
    c.init(Cipher.ENCRYPT_MODE, k);
    RandomAccessFile raf = new RandomAccessFile(path, "rw");

    byte[] buf = new byte[256];
    byte[] output;
    int bytesRead = 0;
    int totalBytes = 0;
    while ((bytesRead = raf.read(buf)) >= 0) {
        int len = buf.length;
        if (bytesRead < len) {
            byte[] out2 = c.doFinal(buf, 0 , bytesRead);
            raf.seek(totalBytes);
            raf.write(out2);
        } else {
        output = c.update(buf, 0, bytesRead);
        raf.seek(totalBytes);
        raf.write(output);
        }
        totalBytes += bytesRead;
        }
    raf.getFD().sync();
    raf.close();
    }

解密示例

为 BBC 计算的数据显示,在英格兰的新收费制度下,一些毕业生最终可能会偿还双倍的学生贷款。

主要会计师提供的数据显示,学生为三年制课程借款 39,000 英镑 \ܯ]£^* z§DþÒÐùN\ܯ]£^ *z§DþÒÐùNree-year course ree-year course 可以偿还以现金计算,总计高达 83,000 英镑。

根据该制度,从 2012 年开始,毕业生将在 30 年内偿还 9% 的收入。

政府表示,该系统是公平的,从 2012 年起,每年将无法收取高达 9,000 英镑的费用,这将由政府预先支付,但一旦学生开始赚取 21,000 英镑或更多,就会付清。

它像我期望的那样调试和运行,我仍然对这些字节/重复是如何到达这里感到困惑。(可能是填充或不正确的doFinal)任何建议将不胜感激:]谢谢!

4

2 回答 2

1

好的,发出的似乎是我没有考虑到每个更新的最后 16 个字节被附加到下一个调用。通过向 raf.seek 添加 16 个字节,我们与数据保持一致并正确附加 doFinal。同样使用 output.length 似乎可以将正确的参数授予文件指针.. in 和输出的 md5s 是准确的,所以似乎有效!:] 解密函数使用 raf.setLength(totalBytes+output.length);

    public static void encryptFile(String path, byte[] key) throws Exception {

    Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
    SecretKeySpec k = new SecretKeySpec(key, "AES");
    c.init(Cipher.ENCRYPT_MODE, k);
    RandomAccessFile raf = new RandomAccessFile(path, "rw");

    byte[] buf = new byte[128];
    int bytesRead = 0;
    int totalBytes = 0;
    byte[] output;
    while ((bytesRead = raf.read(buf)) >= 0) {
        output = c.update(buf, 0, bytesRead);
        raf.seek(totalBytes);
        raf.write(output);
        totalBytes += output.length;
        raf.seek(totalBytes+16);
    }
    output = c.doFinal();
    raf.seek(totalBytes);
    raf.write(output);
    raf.getFD().sync();
    raf.close();

}
于 2011-03-17T20:01:16.060 回答
0

如果原始文件有长度L,那么加密文件将L+delta因为填充而有长度。然后,当您就地解密时,您将写出正确的字节,但文件末尾L仍会保留字节。delta

如果你raf.setLength(totalBytes)在你的 while 循环之后调用,你应该得到正确的结果。

于 2011-03-17T11:01:58.730 回答