【问题标题】:Encrypt/decrypt last 64 KB of file加密/解密最后 64 KB 的文件
【发布时间】:2013-09-25 06:51:23
【问题描述】:

我正在尝试加密/解密文件的最后 64 KB,但加密文件中缺少其中一个文件夹。在这里,我试图在一个 zip 文件上实现。目前,zip 文件中有 3 个文件夹,在生成的 zip 中,它只显示两个文件夹。缺少其中一个文件夹。我认为它缺少一些字节。这是我的代码:

static void encryptLast64KB(String inputPath, String outputPath)
throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {


    File myFile = new File(inputPath);
    FileInputStream fis = new FileInputStream(myFile);

    FileOutputStream fos = new FileOutputStream(outputPath);
    BufferedOutputStream bus = new BufferedOutputStream(fos);

    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),
            "AES");

    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks);

    int b = 0;
    byte[] d = new byte[65536];

    int offset = 0;

    byte[] encVal = null;

    while ((b = fis.read(d)) != -1) {

        offset = offset + b;
        Log.d(TAG, "Offset: "+offset);
        Log.d(TAG, "b: "+b);
        if((offset)>=myFile.length())
        {
            Log.d(TAG, "last 64 Kbytes");

            try {
                encVal = cipher.doFinal(d);
                Log.d(TAG, "encVal: "+encVal);
                bus.write(encVal);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        else
        {
            Log.d(TAG, "rest of the bytes");
            bus.write(d);
        }


        bus.flush();
        bus.close();
        fis.close();
    }


}

请检查..

[已编辑] 添加了用于解密最后 64 KB 的解密代码。

 static byte[] decryptLast64KBytes(String inputPath) throws IOException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException {

        FileInputStream fis = new FileInputStream(inputPath);

        SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] iv = new byte[] { '3', 'd', '0', 'c', 'd', '7', 'A', '9', '7', 'e', '2', '0', 'b', 'x', 'g', 'y' };
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        try {
            cipher.init(Cipher.DECRYPT_MODE, sks, ivParameterSpec);
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        CipherInputStream cis = new CipherInputStream(fis, cipher);

        int b;
        byte[] d = new byte[1024];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int count =0;

        int offset = 0;
        while((b = fis.read(d)) != -1) {
            offset = offset + b;
            Log.d(TAG, "Offset: "+offset);
            Log.d(TAG, "b: "+b);
            if((offset)>=fis.available())
            {
                Log.d(TAG, "last 64 Kbytes");
                while((b = cis.read(d, offset, offset+b))!=-1)
                {
                    bos.write(d);
                    offset = offset + b;
                }

            }
            else
            {
                Log.d(TAG, "rest of the bytes");
                bos.write(d);
            }

        }

        byte[] completeBytes = bos.toByteArray();
        cis.close();
        return completeBytes;

}

【问题讨论】:

  • 为什么只加密最后一块数据?顺便提一句。它几乎总是小于 64kB,例如,如果你的文件是 70kB,它可能只有 5kB 左右。鉴于read 的合约允许返回少于请求的字节数,也不可能知道加密部分从哪里开始。

标签: java android encryption


【解决方案1】:

我认为,如果要加密不是 8 字节块的倍数的文本消息,则必须在文本消息中填充附加字节以使文本消息成为 8 的倍数-字节块。

试试

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

带有初始化向量:

byte[] iv = new byte[] { '3', 'd', '0', 'c', 'd', '7', 'A', '9', '7', 'e', '2', '0', 'b', 'x', 'g', 'y' };
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

小评:在我看来,你的字节数组太大了,1024应该没问题

byte[] bytes = new byte[1024];

请注意,您可以使用 CipherOutputStream 和 CipherInputStream 来隐藏加密和写入/读取字节的详细信息。对于这些要求,我实际上会建议这样做。

FileInputStream fis = new FileInputStream(inputFileName);
CipherInputStream cis = new CipherInputStream(fis, cipher);

【讨论】:

  • 嗨,非常感谢@Antho,加密现在工作正常......但问题仍然存在于解密中
  • 尝试使用以下命令:FileOutputStream.write(byte[] b, int off, int len)" 从偏移量 off 开始的指定字节数组中写入 len 个字节到此文件输出流。跨度>
【解决方案2】:

您的代码未加密最后 64KB。它加密最后一个块,不管它的大小,都是由所有先前的读取产生的。如果你想要最后的64KB,天知道为什么,你得seek()或者skip()到合适的值,也就是文件长度减去64KB。

【讨论】:

    猜你喜欢
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多