Move cipher logic out of backup and restore components
This commit is contained in:
parent
b182e743e8
commit
9b979b3693
4 changed files with 68 additions and 21 deletions
|
@ -0,0 +1,57 @@
|
|||
package com.stevesoltys.backup.security;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
/**
|
||||
* A utility class for encrypting and decrypting data using a {@link Cipher}.
|
||||
*
|
||||
* @author Steve Soltys
|
||||
*/
|
||||
public class CipherUtil {
|
||||
|
||||
/**
|
||||
* The cipher algorithm.
|
||||
*/
|
||||
public static final String CIPHER_ALGORITHM = "AES/CFB/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* Encrypts the given payload using a key generated from the provided password and salt.
|
||||
*
|
||||
* @param payload The payload.
|
||||
* @param password The password.
|
||||
* @param salt The salt.
|
||||
*/
|
||||
public static byte[] encrypt(byte[] payload, String password, byte[] salt) throws NoSuchPaddingException,
|
||||
NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException {
|
||||
|
||||
SecretKey secretKey = KeyGenerator.generate(password, salt);
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(salt));
|
||||
|
||||
return cipher.doFinal(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the given payload using a key generated from the provided password and salt.
|
||||
*
|
||||
* @param payload The payload.
|
||||
* @param password The password.
|
||||
* @param salt The salt.
|
||||
*/
|
||||
public static byte[] decrypt(byte[] payload, String password, byte[] salt) throws NoSuchPaddingException,
|
||||
NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException {
|
||||
|
||||
SecretKey secretKey = KeyGenerator.generate(password, salt);
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(salt));
|
||||
|
||||
return cipher.doFinal(payload);
|
||||
}
|
||||
}
|
|
@ -6,19 +6,15 @@ import android.content.pm.PackageInfo;
|
|||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import com.stevesoltys.backup.security.KeyGenerator;
|
||||
import com.stevesoltys.backup.security.CipherUtil;
|
||||
import com.stevesoltys.backup.transport.component.BackupComponent;
|
||||
import libcore.io.IoUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
@ -262,14 +258,12 @@ public class ContentProviderBackupComponent implements BackupComponent {
|
|||
|
||||
try {
|
||||
if (configuration.getPassword() != null && !configuration.getPassword().isEmpty()) {
|
||||
SecretKey secretKey = KeyGenerator.generate(configuration.getPassword(), backupState.getSalt());
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ContentProviderBackupConstants.CIPHER_ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(backupState.getSalt()));
|
||||
|
||||
byte[] payload = Arrays.copyOfRange(buffer, 0, dataSize);
|
||||
byte[] encryptedBuffer = cipher.doFinal(payload);
|
||||
outputStream.write(encryptedBuffer);
|
||||
String password = configuration.getPassword();
|
||||
byte[] salt = backupState.getSalt();
|
||||
|
||||
outputStream.write(CipherUtil.encrypt(payload, password, salt));
|
||||
|
||||
} else {
|
||||
outputStream.write(buffer, 0, dataSize);
|
||||
|
|
|
@ -3,9 +3,7 @@ package com.stevesoltys.backup.transport.component.provider;
|
|||
/**
|
||||
* @author Steve Soltys
|
||||
*/
|
||||
public class ContentProviderBackupConstants {
|
||||
|
||||
static final String CIPHER_ALGORITHM = "AES/CFB/PKCS5Padding";
|
||||
class ContentProviderBackupConstants {
|
||||
|
||||
static final String SALT_FILE_PATH = "salt";
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.os.ParcelFileDescriptor;
|
|||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.stevesoltys.backup.security.CipherUtil;
|
||||
import com.stevesoltys.backup.security.KeyGenerator;
|
||||
import com.stevesoltys.backup.transport.component.RestoreComponent;
|
||||
import libcore.io.IoUtils;
|
||||
|
@ -179,14 +180,11 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
|
|||
private byte[] readBackupData(ZipInputStream inputStream) throws Exception {
|
||||
byte[] backupData = Streams.readFullyNoClose(inputStream);
|
||||
|
||||
if (configuration.getPassword() != null && !configuration.getPassword().isEmpty() &&
|
||||
restoreState.getSalt() != null) {
|
||||
String password = configuration.getPassword();
|
||||
byte[] salt = restoreState.getSalt();
|
||||
|
||||
SecretKey secretKey = KeyGenerator.generate(configuration.getPassword(), restoreState.getSalt());
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ContentProviderBackupConstants.CIPHER_ALGORITHM);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(restoreState.getSalt()));
|
||||
backupData = cipher.doFinal(backupData);
|
||||
if (password != null && !password.isEmpty() && salt != null) {
|
||||
backupData = CipherUtil.decrypt(backupData, password, salt);
|
||||
}
|
||||
|
||||
return backupData;
|
||||
|
|
Loading…
Reference in a new issue