All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.isaichkindanila.crypt.lib.stream.EncryptedOutputStream Maven / Gradle / Ivy

The newest version!
package com.github.isaichkindanila.crypt.lib.stream;

import com.github.isaichkindanila.crypt.lib.cipher.StandardStreamCipher;
import com.github.isaichkindanila.crypt.lib.cipher.StreamCipher;

import java.io.IOException;
import java.io.OutputStream;

/**
 * {@code OutputStream} wrapper used to encrypt data as it's being written.
 *
 * @see DecryptedInputStream
 */
public class EncryptedOutputStream extends OutputStream {
    private final byte[] buffer = new byte[CryptStream.BUFFER_SIZE];
    private final OutputStream out;
    private final StreamCipher cipher;

    /**
     * @param out      wrapped {@code OutputStream}
     * @param cipher   cipher to encrypt data with
     * @param password password to be used as cipher key
     * @throws IOException if {@code IOException} occurs while stream header is being written
     */
    public EncryptedOutputStream(OutputStream out, StandardStreamCipher cipher, String password) throws IOException {
        CryptStream stream = new CryptStream(null, out);
        stream.writeStreamSignature();

        byte[] key = stream.hash(password);
        byte[] iv = stream.writeIV();

        stream.writeCipher(cipher);

        this.cipher = cipher.newInstance(key, iv);
        this.out = out;

        byte[] passHash = stream.hash(key, iv);
        this.write(passHash);
    }

    /**
     * Encrypts and writes a byte to wrapped stream.
     *
     * @param b byte to encrypt and write to wrapped stream
     * @throws IOException if IOException occurs
     */
    @Override
    public void write(int b) throws IOException {
        out.write(cipher.apply((byte) b));
    }

    @Override
    public void write(byte[] b) throws IOException {
        write(b, 0, b.length);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        while (len > 0) {
            int size = Math.min(len, CryptStream.BUFFER_SIZE);
            System.arraycopy(b, off, buffer, 0, size);

            cipher.apply(buffer, 0, size);
            out.write(buffer, 0, size);

            off += size;
            len -= size;
        }
    }

    @Override
    public void flush() throws IOException {
        out.flush();
    }

    @Override
    public void close() throws IOException {
        out.close();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy