我可以在 Java 中仅解密使用 AES/CBC 加密的文件的一部分吗?

ed2*_*d22 4 java encryption aes cbc-mode

我该怎么办呢?我有使用 Java 中的 AES/CBC/PKCS5Padding 加密文件的代码,据我从这张图片中了解到:在此输入图像描述

部分解密应该可以通过前面的块和密钥使用部分密文来实现。不过,我还没有找到任何这方面的例子。有什么帮助吗?

解密代码如下:

    //skip the IV (ivSize is 16 here) - IV was pretended to the stream during encryption
    data.skip(ivSize);
    //skip n blocks
    int n = 2;
    System.out.println("skipped: " + data.skip(n*16));

    byte[] iv = new byte[ivSize];
    //use next 16 bytes as IV
    data.read(iv);

    // Hashing key.
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    digest.update(encryptionKey.getBytes(StandardCharsets.UTF_8));
    byte[] keyBytes = new byte[16];
    System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);

    Cipher cipher;
    try {
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
    } catch (GeneralSecurityException e) {
        throw new IOException(e);
    }

    CipherInputStream cis = new CipherInputStream(data, cipher);
    try {
        ByteStreams.copy(ByteStreams.limit(cis, limit), output);
    } catch (IOException exception) {
        // starting with java 8 the JVM wraps an IOException around a GeneralSecurityException
        // it should be safe to swallow a GeneralSecurityException
        if (!(exception.getCause() instanceof GeneralSecurityException)) {
            throw exception;
        }
        log.warning(exception.getMessage());
    } finally {
        cis.close();
    }
Run Code Online (Sandbox Code Playgroud)

zap*_*aph 5

对的,这是可能的。

您需要选择块边界上的“部分”,长度是块大小的倍数,并使用前一个块作为 IV。对于 AES,块大小为 16 字节。

如果“部分”包括最后一个块,请指定正确的填充,否则指定无填充NoPaddingAES/CBC/NoPadding在本例中。这将消除填充错误。只有最后一个块有填充。

Cipher必须使用正确的填充选项进行实例化,具体取决于它是否是整个加密数据的最后一个块。

请参阅:PKCS#7 填充(有时错误地称为 PKCS#5),这是最常见的填充。