Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I decrypt only part of file encrypted with AES/CBC in Java?

How would I go about this? I have code encrypting a file using AES/CBC/PKCS5Padding in Java and as I understand form this picture: enter image description here

Partial decryption should be possible having part of ciphertext used by preceding block and the key. I have not found any examples of this, though. Any help?

The decrypting code is as fallows:

    //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();
    }
like image 830
ed22 Avatar asked Nov 02 '25 13:11

ed22


1 Answers

Yes it is possible.

You need to choose the "part" on a block boundary, a length that is a block size multiple and use the previous block as the IV. For AES the block size is 16-bytes.

If the "part" includes the last block specify the correct padding, otherwise specify no padding NoPadding: AES/CBC/NoPadding in this instance. This will eliminate a padding error. Only there last block is has/is padding.

Cipher must be instantiated with the correct padding option depending if it is the last block of the entire encrypted data or not.

See: PKCS#7 padding (sometimes called PKCS#5 in error) which is the most common padding.

like image 118
zaph Avatar answered Nov 04 '25 05:11

zaph



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!