Javaで暗号ストリームを検索します。それらを使用してストリームをその場で暗号化/復号化できるため、すべてをメモリに保存する必要はありません。あなたがしなければならないのはFileInputStream
、あなたのソースファイルのレギュラーを暗号化されたシンクファイルのCipherOutputStream
あなたをラップしているものにコピーすることです。このコピーを作成するためのメソッドも便利に含まれています。FileOutputStream
IOUtils
copy(InputStream, OutputStream)
例えば:
public static void main(String[] args) {
encryptFile("exampleInput.txt", "exampleOutput.txt");
}
public static void encryptFile(String source, String sink) {
FileInputStream fis = null;
try {
fis = new FileInputStream(source);
CipherOutputStream cos = null;
try {
cos = new CipherOutputStream(new FileOutputStream(sink), getEncryptionCipher());
IOUtils.copy(fis, cos);
} finally {
if (cos != null)
cos.close();
}
} finally {
if (fis != null)
fis.close();
}
}
private static Cipher getEncryptionCipher() {
// Create AES cipher with whatever padding and other properties you want
Cipher cipher = ... ;
// Create AES secret key
Key key = ... ;
cipher.init(Cipher.ENCRYPT_MODE, key);
}
コピーされたバイト数を知る必要がある場合は、ファイルサイズがバイト(2 GB)を超えるかどうかのIOUtils.copyLarge
代わりに使用できます。IOUtils.copy
Integer.MAX_VALUE
ファイルを復号化するには、同じことを行いますが、のCipherInputStream
代わりにを使用し、 usingCipherOutputStream
を初期化します。Cipher
Cipher.DECRYPT_MODE
Javaの暗号化ストリームの詳細については、こちらをご覧ください。
byte
これにより、独自の配列を格納する必要がなくなるため、スペースを節約できます。このシステムに保存さbyte[]
れるのは、の内部のみです。これbyte[]
は、十分な入力が入力され、暗号化されたブロックがによって返されるたびに、またはが閉じられるとオンにCipher
なるたびにクリアされます。ただし、これはすべて内部であり、すべてが管理されているため、これについて心配する必要はありません。Cipher.update
Cipher.doFinal
CipherOutputStream
編集:これにより、特定の暗号化例外が無視される可能性があることに注意してください。特にBadPaddingException
、IllegalBlockSizeException
。この動作は、CipherOutputStream
ソースコードに記載されています。(確かに、このソースはOpenJDKからのものですが、おそらくSun JDKでも同じことを行います。)また、CipherOutputStream javadocsから:
java.io.OutputStream
このクラスは、その祖先クラスとのセマンティクス、特に失敗セマンティクスに厳密に準拠していjava.io.FilterOutputStream
ます。このクラスには、その祖先クラスで指定されたメソッドが正確にあり、それらすべてをオーバーライドします。さらに、このクラスは、その祖先クラスによってスローされないすべての例外をキャッチします。
ここでの太線は、暗号化例外が無視されることを意味します。これにより、特にAESのようなブロックおよび/またはパディング暗号化アルゴリズムの場合、暗号化されたファイルを読み取ろうとしているときに予期しない動作が発生する可能性があります。CipherInputStream
暗号化された(または復号化された)ファイルの出力がゼロまたは部分的になることに注意してください。