代码之家  ›  专栏  ›  技术社区  ›  menteith

加密要通过Amazon S3发送的大流

  •  1
  • menteith  · 技术社区  · 6 年前

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   gagan singh    6 年前

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