use buffers for encryption, so large files work as well... also showing encryption progress with better accuracy, which is especially useful for large encryptions

Fixes issue 18.
This commit is contained in:
Thialfihar 2010-05-04 14:07:18 +00:00
parent 778f51dbaa
commit e542c37eb3
5 changed files with 41 additions and 43 deletions

View file

@ -1198,6 +1198,7 @@ public class Apg {
} }
public static void encrypt(InputStream inStream, OutputStream outStream, public static void encrypt(InputStream inStream, OutputStream outStream,
long dataLength,
boolean armored, boolean armored,
long encryptionKeyIds[], long signatureKeyId, long encryptionKeyIds[], long signatureKeyId,
String signaturePassPhrase, String signaturePassPhrase,
@ -1240,23 +1241,13 @@ public class Apg {
if (signaturePassPhrase == null) { if (signaturePassPhrase == null) {
throw new GeneralException("no pass phrase given"); throw new GeneralException("no pass phrase given");
} }
progress.setProgress("extracting signature key...", 0, 100);
signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(), signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(),
new BouncyCastleProvider()); new BouncyCastleProvider());
} }
PGPSignatureGenerator signatureGenerator = null; PGPSignatureGenerator signatureGenerator = null;
progress.setProgress("preparing data...", 0, 100); progress.setProgress("preparing streams...", 5, 100);
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
int n = 0;
byte[] buffer = new byte[1 << 16];
while ((n = inStream.read(buffer)) > 0) {
byteOut.write(buffer, 0, n);
}
byteOut.close();
byte messageData[] = byteOut.toByteArray();
progress.setProgress("preparing streams...", 20, 100);
// encryptFile and compress input file content // encryptFile and compress input file content
PGPEncryptedDataGenerator cPk = PGPEncryptedDataGenerator cPk =
new PGPEncryptedDataGenerator(symmetricAlgorithm, true, new SecureRandom(), new PGPEncryptedDataGenerator(symmetricAlgorithm, true, new SecureRandom(),
@ -1275,7 +1266,7 @@ public class Apg {
encryptOut = cPk.open(out, new byte[1 << 16]); encryptOut = cPk.open(out, new byte[1 << 16]);
if (signatureKeyId != 0) { if (signatureKeyId != 0) {
progress.setProgress("preparing signature...", 30, 100); progress.setProgress("preparing signature...", 10, 100);
signatureGenerator = signatureGenerator =
new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(), new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(),
hashAlgorithm, hashAlgorithm,
@ -1298,19 +1289,27 @@ public class Apg {
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
// file name not needed, so empty string // file name not needed, so empty string
OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "",
messageData.length, new Date()); new Date(), new byte[1 << 16]);
progress.setProgress("encrypting...", 40, 100); progress.setProgress("encrypting...", 20, 100);
pOut.write(messageData); long done = 0;
int n = 0;
if (signatureKeyId != 0) { byte[] buffer = new byte[1 << 16];
progress.setProgress("finishing signature...", 70, 100); while ((n = inStream.read(buffer)) > 0) {
signatureGenerator.update(messageData); pOut.write(buffer, 0, n);
if (signatureKeyId != 0) {
signatureGenerator.update(buffer, 0, n);
}
done += n;
if (dataLength != 0) {
progress.setProgress((int) (20 + (95 - 20) * done / dataLength), 100);
}
} }
literalGen.close(); literalGen.close();
if (signatureKeyId != 0) { if (signatureKeyId != 0) {
progress.setProgress("generating signature...", 95, 100);
signatureGenerator.generate().encode(pOut); signatureGenerator.generate().encode(pOut);
} }
compressGen.close(); compressGen.close();
@ -1516,7 +1515,7 @@ public class Apg {
throw new GeneralException("couldn't find a packet with symmetric encryption"); throw new GeneralException("couldn't find a packet with symmetric encryption");
} }
progress.setProgress("decrypting data...", 20, 100); progress.setProgress("preparing streams...", 20, 100);
clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider()); clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider());
encryptedData = pbe; encryptedData = pbe;
} else { } else {
@ -1550,7 +1549,7 @@ public class Apg {
throw new PGPException("wrong pass phrase"); throw new PGPException("wrong pass phrase");
} }
progress.setProgress("decrypting data...", 30, 100); progress.setProgress("preparing streams...", 30, 100);
clear = pbe.getDataStream(privateKey, new BouncyCastleProvider()); clear = pbe.getDataStream(privateKey, new BouncyCastleProvider());
encryptedData = pbe; encryptedData = pbe;
} }
@ -1606,9 +1605,9 @@ public class Apg {
} }
if (dataChunk instanceof PGPLiteralData) { if (dataChunk instanceof PGPLiteralData) {
progress.setProgress("unpacking data...", 70, 100); progress.setProgress("decrypting data...", 70, 100);
PGPLiteralData literalData = (PGPLiteralData) dataChunk; PGPLiteralData literalData = (PGPLiteralData) dataChunk;
BufferedOutputStream out = new BufferedOutputStream(outStream); OutputStream out = outStream;
byte[] buffer = new byte[1 << 16]; byte[] buffer = new byte[1 << 16];
InputStream dataIn = literalData.getInputStream(); InputStream dataIn = literalData.getInputStream();

View file

@ -183,14 +183,9 @@ public class DecryptFileActivity extends BaseActivity {
try { try {
InputStream in = new FileInputStream(mInputFilename); InputStream in = new FileInputStream(mInputFilename);
ByteArrayOutputStream out = new ByteArrayOutputStream(); OutputStream out = new FileOutputStream(mOutputFilename);
data = Apg.decrypt(in, out, Apg.getPassPhrase(), this, mAssumeSymmetricEncryption); data = Apg.decrypt(in, out, Apg.getPassPhrase(), this, mAssumeSymmetricEncryption);
out.close();
OutputStream fileOut = new FileOutputStream(mOutputFilename);
fileOut.write(out.toByteArray());
fileOut.close();
} catch (PGPException e) { } catch (PGPException e) {
error = e.getMessage(); error = e.getMessage();
} catch (IOException e) { } catch (IOException e) {

View file

@ -333,7 +333,7 @@ public class EncryptFileActivity extends BaseActivity {
} }
InputStream in = new FileInputStream(mInputFilename); InputStream in = new FileInputStream(mInputFilename);
ByteArrayOutputStream out = new ByteArrayOutputStream(); OutputStream out = new FileOutputStream(mOutputFilename);
String passPhrase = null; String passPhrase = null;
if (mEncryptionMode.getCheckedRadioButtonId() == R.id.use_symmetric) { if (mEncryptionMode.getCheckedRadioButtonId() == R.id.use_symmetric) {
@ -342,17 +342,18 @@ public class EncryptFileActivity extends BaseActivity {
passPhrase = null; passPhrase = null;
} }
} }
Apg.encrypt(in, out, mAsciiArmour.isChecked(),
mEncryptionKeyIds, getSecretKeyId(), File file = new File(mInputFilename);
Apg.getPassPhrase(), this, long fileSize = file.length();
((Choice) mAlgorithm.getSelectedItem()).getId(),
getDefaultHashAlgorithm(), Apg.encrypt(in, out, fileSize, mAsciiArmour.isChecked(),
passPhrase); mEncryptionKeyIds, getSecretKeyId(),
Apg.getPassPhrase(), this,
((Choice) mAlgorithm.getSelectedItem()).getId(),
getDefaultHashAlgorithm(),
passPhrase);
out.close(); out.close();
OutputStream fileOut = new FileOutputStream(mOutputFilename);
fileOut.write(out.toByteArray());
fileOut.close();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
error = "file not found: " + e.getMessage(); error = "file not found: " + e.getMessage();
} }

View file

@ -193,12 +193,12 @@ public class EncryptMessageActivity extends BaseActivity {
message = message.replaceFirst("\n*$", "\n"); message = message.replaceFirst("\n*$", "\n");
} }
ByteArrayInputStream in = byte[] byteData = Strings.toUTF8ByteArray(message);
new ByteArrayInputStream(Strings.toUTF8ByteArray(message)); ByteArrayInputStream in = new ByteArrayInputStream(byteData);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
if (encryptIt) { if (encryptIt) {
Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(), Apg.encrypt(in, out, byteData.length, true, mEncryptionKeyIds, getSecretKeyId(),
Apg.getPassPhrase(), this, Apg.getPassPhrase(), this,
getDefaultEncryptionAlgorithm(), getDefaultHashAlgorithm(), getDefaultEncryptionAlgorithm(), getDefaultHashAlgorithm(),
null); null);

View file

@ -221,6 +221,9 @@ public class MainActivity extends BaseActivity {
SpannableString info = SpannableString info =
new SpannableString("Read the warnings!\n\n" + new SpannableString("Read the warnings!\n\n" +
"Changes:\n" + "Changes:\n" +
"* fixed several crashes\n" +
"* can encrypt large files\n" +
"* better progress bar calculation\n" +
"\n" + "\n" +
"WARNING: be careful editing your existing keys, as they " + "WARNING: be careful editing your existing keys, as they " +
"WILL be stripped of certificates right now.\n" + "WILL be stripped of certificates right now.\n" +