加密要通过Amazon S3发送的大型流 [英] Encrypting large streams to be sent via Amazon S3
问题描述
我想加密流,然后使用Amazon S3发送.我正在使用旧版代码,并且有两个重要参数:未加密的InputStream
及其长度.这很重要,因为AmazonS3Client希望在上传之前知道流的长度.
I want to encrypt stream and then send it using Amazon S3. I'm using legacy code and have two important parameters: non-encrypted InputStream
and its length. This is important as AmazonS3Client wants to know the length of the stream before it uploads it.
加密流不是很困难的任务:
Encrypting a stream is not very difficult task:
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.
However, this approach could be used for small files only as their are written to a byte array held in memory. The thing is that I'd like to encrypt big files (> 1TB). How do I do this? More specifically, I get InputStream and my job is to return encrypted InputStream that will be used by Amazon S3.
推荐答案
请勿使用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);
这篇关于加密要通过Amazon S3发送的大型流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!