java - 加密通过 Amazon S3 发送的大流

标签 java encryption amazon-s3

我想加密流,然后使用 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);

但是,这种方法只能用于小文件,因为它们被写入内存中保存的字节数组。问题是我想加密大文件(> 1TB)。我该怎么做呢?更具体地说,我获取了 InputStream,我的工作是返回将由 Amazon S3 使用的加密 InputStream。

最佳答案

不要使用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);

关于java - 加密通过 Amazon S3 发送的大流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51117639/

相关文章:

java - 如何在流式 json 中使用 jackson 的上下文?

java - Quarkus,无法使用 slf4j 登录单元测试

c - c编程中使用openssl使用文件IO进行三重DES加密解密

amazon-s3 - 为相同的 Cloudfront 发行版为不同的来源配置不同的错误页面

c++ - AWS S3 C++ : List all the object when result is truncated

java - 用 root 根页面替换/设置 tomcat 欢迎页面

java - 为 Bigdecimal 生成动态标度

c# - 来自 C# 应用程序的加密

java - AES 加密 - 以后如何解密加密的字符串?

json - 创建 AWS::KMS::Key 时出现 MalformedPolicyDocumentException