Example usage for java.nio ByteBuffer putLong

List of usage examples for java.nio ByteBuffer putLong

Introduction

In this page you can find the example usage for java.nio ByteBuffer putLong.

Prototype

public abstract ByteBuffer putLong(int index, long value);

Source Link

Document

Writes the given long to the specified index of this buffer.

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);/*ww w. ja v  a2  s  .  co m*/

    // 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);
    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.apache.hadoop.crypto.CryptoStreamsTestBase.java

private void setCounterBaseForIV(byte[] iv, long counterBase) {
    ByteBuffer buf = ByteBuffer.wrap(iv);
    buf.order(ByteOrder.BIG_ENDIAN);
    buf.putLong(iv.length - 8, counterBase);
}

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

@Override
public Long decryptRange(SeekableByteChannel encryptedFile, OutputStream plaintextFile, long pos, long length)
        throws IOException {
    // read iv:/*from w w  w .ja va  2 s .  c  o  m*/
    encryptedFile.position(0);
    final ByteBuffer countingIv = ByteBuffer.allocate(AES_BLOCK_LENGTH);
    final int numIvBytesRead = encryptedFile.read(countingIv);

    // check validity of header:
    if (numIvBytesRead != AES_BLOCK_LENGTH) {
        throw new IOException("Failed to read file header.");
    }

    // seek relevant position and update iv:
    long firstRelevantBlock = pos / AES_BLOCK_LENGTH; // cut of fraction!
    long beginOfFirstRelevantBlock = firstRelevantBlock * AES_BLOCK_LENGTH;
    long offsetInsideFirstRelevantBlock = pos - beginOfFirstRelevantBlock;
    countingIv.putLong(AES_BLOCK_LENGTH - Long.BYTES, firstRelevantBlock);

    // fast forward stream:
    encryptedFile.position(64 + beginOfFirstRelevantBlock);

    // generate cipher:
    final Cipher cipher = this.aesCtrCipher(primaryMasterKey, countingIv.array(), Cipher.DECRYPT_MODE);

    // read content
    final InputStream in = new SeekableByteChannelInputStream(encryptedFile);
    final InputStream cipheredIn = new CipherInputStream(in, cipher);
    return IOUtils.copyLarge(cipheredIn, plaintextFile, offsetInsideFirstRelevantBlock, length);
}