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

View File

@ -183,14 +183,9 @@ public class DecryptFileActivity extends BaseActivity {
try {
InputStream in = new FileInputStream(mInputFilename);
ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStream out = new FileOutputStream(mOutputFilename);
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) {
error = e.getMessage();
} catch (IOException e) {

View File

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

View File

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

View File

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