我只能解密用Java中的AES / CBC加密的部分文件吗?

时间:2018-02-16 15:51:55

标签: java encryption aes cbc-mode

我该怎么做?我有使用Java中的AES / CBC / PKCS5Padding加密文件的代码,据我了解这张图片:enter image description here

部分解密应该可以使用前一个块和密钥使用的密文的一部分。但是,我没有找到任何这方面的例子。有什么帮助吗?

解密代码如下:

    //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();
    }

1 个答案:

答案 0 :(得分:4)

是的,这是可能的。

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

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

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

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