Шифрование больших потоков для отправки через Amazon S3 - PullRequest
0 голосов
/ 30 июня 2018

Я хочу зашифровать поток и затем отправить его с помощью Amazon S3. Я использую устаревший код и имею два важных параметра: незашифрованный InputStream и его длину. Это важно, так как AmazonS3Client хочет знать длину потока, прежде чем загружать его.

Шифрование потока не очень сложная задача:

        InputStream in = new FileInputStream("path-to-file");
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        Key key = keygen.generateKey();

        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, key);

        OutputStream encryptedStream = new ByteArrayOutputStream();
        CipherOutputStream out = new CipherOutputStream(encryptedStream, cipher);
        out.write(in.read());
        out.flush();

        byte[] bytes = ((ByteArrayOutputStream) encryptedStream).toByteArray();
        InputStream encryptedInput = new ByteArrayInputStream(bytes);

Однако этот подход можно использовать только для небольших файлов, поскольку они записываются в байтовый массив, хранящийся в памяти. Дело в том, что я хотел бы зашифровать большие файлы (> 1 ТБ). Как мне это сделать? Более конкретно, я получаю InputStream, и моя задача - вернуть зашифрованный InputStream, который будет использоваться Amazon S3.

1 Ответ

0 голосов
/ 30 июня 2018

не использовать ByteArrayOutputStream

    InputStream in = new FileInputStream("path-to-file");
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    Key key = keygen.generateKey();

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);

    try(CipherOutputStream out = new CipherOutputStream(
            new FileOutputStream(new File("path to enc file")), cipher))
    {
        byte[] buffer = new byte[8192];
        int count;
        while ((count = in.read(buffer)) > 0)
        {
            out.write(buffer, 0, count);
        }
    }

    return new FileInputStream(new File("path to enc file"));

Еще один ответ с потоковыми каналами.

    InputStream in = new FileInputStream("path-to-file");
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    Key key = keygen.generateKey();

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);

    PipedOutputStream pout = new PipedOutputStream();
    //write data in a separate thread.
    new Thread(() -> {
        try(CipherOutputStream out = new CipherOutputStream(
                pout, cipher))
        {
            byte[] buffer = new byte[8192];
            int count;
            while ((count = in.read(buffer)) > 0)
            {
                out.write(buffer, 0, count);
            }
        } catch (IOException  e)
        {
            e.printStackTrace();
        }
    }).start();

    return new PipedInputStream(pout);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...