Example usage for java.nio.channels SeekableByteChannel truncate

List of usage examples for java.nio.channels SeekableByteChannel truncate

Introduction

In this page you can find the example usage for java.nio.channels SeekableByteChannel truncate.

Prototype

SeekableByteChannel truncate(long size) throws IOException;

Source Link

Document

Truncates the entity, to which this channel is connected, to the given size.

Usage

From source file:org.cryptomator.crypto.aes256.Aes256Cryptor.java

@Override
public Long encryptFile(InputStream plaintextFile, SeekableByteChannel encryptedFile) throws IOException {
    // truncate file
    encryptedFile.truncate(0);

    // use an IV, whose last 8 bytes store a long used in counter mode and write initial value to file.
    final ByteBuffer countingIv = ByteBuffer.wrap(randomData(AES_BLOCK_LENGTH));
    countingIv.putLong(AES_BLOCK_LENGTH - Long.BYTES, 0l);
    countingIv.position(0);/*from   w  w w.j  a v  a 2s. c o  m*/
    encryptedFile.write(countingIv);

    // init crypto stuff:
    final Mac mac = this.hmacSha256(hMacMasterKey);
    final Cipher cipher = this.aesCtrCipher(primaryMasterKey, countingIv.array(), Cipher.ENCRYPT_MODE);

    // init mac buffer and skip 32 bytes
    final ByteBuffer macBuffer = ByteBuffer.allocate(mac.getMacLength());
    encryptedFile.write(macBuffer);

    // init filesize buffer and skip 16 bytes
    final ByteBuffer encryptedFileSizeBuffer = ByteBuffer.allocate(AES_BLOCK_LENGTH);
    encryptedFile.write(encryptedFileSizeBuffer);

    // write content:
    final OutputStream out = new SeekableByteChannelOutputStream(encryptedFile);
    final OutputStream macOut = new MacOutputStream(out, mac);
    final OutputStream cipheredOut = new CipherOutputStream(macOut, cipher);
    final OutputStream blockSizeBufferedOut = new BufferedOutputStream(cipheredOut, AES_BLOCK_LENGTH);
    final Long plaintextSize = IOUtils.copyLarge(plaintextFile, blockSizeBufferedOut);

    // ensure total byte count is a multiple of the block size, in CTR mode:
    final int remainderToFillLastBlock = AES_BLOCK_LENGTH - (int) (plaintextSize % AES_BLOCK_LENGTH);
    blockSizeBufferedOut.write(new byte[remainderToFillLastBlock]);

    // append a few blocks of fake data:
    final int numberOfPlaintextBlocks = (int) Math.ceil(plaintextSize / AES_BLOCK_LENGTH);
    final int upToTenPercentFakeBlocks = (int) Math.ceil(Math.random() * 0.1 * numberOfPlaintextBlocks);
    final byte[] emptyBytes = new byte[AES_BLOCK_LENGTH];
    for (int i = 0; i < upToTenPercentFakeBlocks; i += AES_BLOCK_LENGTH) {
        blockSizeBufferedOut.write(emptyBytes);
    }
    blockSizeBufferedOut.flush();

    // write MAC of total ciphertext:
    macBuffer.position(0);
    macBuffer.put(mac.doFinal());
    macBuffer.position(0);
    encryptedFile.position(16); // right behind the IV
    encryptedFile.write(macBuffer); // 256 bit MAC

    // encrypt and write plaintextSize
    try {
        final ByteBuffer fileSizeBuffer = ByteBuffer.allocate(Long.BYTES);
        fileSizeBuffer.putLong(plaintextSize);
        final Cipher sizeCipher = aesEcbCipher(primaryMasterKey, Cipher.ENCRYPT_MODE);
        final byte[] encryptedFileSize = sizeCipher.doFinal(fileSizeBuffer.array());
        encryptedFileSizeBuffer.position(0);
        encryptedFileSizeBuffer.put(encryptedFileSize);
        encryptedFileSizeBuffer.position(0);
        encryptedFile.position(48); // right behind the IV and MAC
        encryptedFile.write(encryptedFileSizeBuffer);
    } catch (IllegalBlockSizeException | BadPaddingException e) {
        throw new IllegalStateException(
                "Block size must be valid, as padding is requested. BadPaddingException not possible in encrypt mode.",
                e);
    }

    return plaintextSize;
}

From source file:org.neo4j.io.fs.FileUtils.java

public static void truncateFile(SeekableByteChannel fileChannel, long position) throws IOException {
    int count = 0;
    boolean success = false;
    IOException cause = null;//from   ww  w.jav a 2  s.  co  m
    do {
        count++;
        try {
            fileChannel.truncate(position);
            success = true;
        } catch (IOException e) {
            cause = e;
        }

    } while (!success && count <= WINDOWS_RETRY_COUNT);
    if (!success) {
        throw cause;
    }
}