mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 13:45:35 +03:00
append salt to private key
This commit is contained in:
parent
d6b9f7e54b
commit
917189f3ca
3 changed files with 39 additions and 20 deletions
|
@ -234,7 +234,21 @@ public class EncryptionTestIT {
|
|||
Set<String> ivs = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
assertTrue(ivs.add(EncryptionUtils.encodeBytesToBase64String(EncryptionUtils.generateIV())));
|
||||
assertTrue(ivs.add(EncryptionUtils.encodeBytesToBase64String(
|
||||
EncryptionUtils.randomBytes(EncryptionUtils.ivLength))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generates new salt and tests if they are unique
|
||||
*/
|
||||
@Test
|
||||
public void testSalt() {
|
||||
Set<String> ivs = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
assertTrue(ivs.add(EncryptionUtils.encodeBytesToBase64String(
|
||||
EncryptionUtils.randomBytes(EncryptionUtils.saltLength))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -511,7 +511,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
}
|
||||
|
||||
if (iv == null || iv.length == 0) {
|
||||
iv = EncryptionUtils.generateIV();
|
||||
iv = EncryptionUtils.randomBytes(EncryptionUtils.ivLength);
|
||||
}
|
||||
|
||||
EncryptionUtils.EncryptedFile encryptedFile = EncryptionUtils.encryptFile(mFile, key, iv);
|
||||
|
|
|
@ -93,15 +93,16 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
public class EncryptionUtils {
|
||||
private static String TAG = EncryptionUtils.class.getSimpleName();
|
||||
|
||||
private static byte[] salt = "$4$YmBjm3hk$Qb74D5IUYwghUmzsMqeNFx5z0/8$".getBytes();
|
||||
public static String PUBLIC_KEY = "PUBLIC_KEY";
|
||||
public static String PRIVATE_KEY = "PRIVATE_KEY";
|
||||
public static int ivLength = 16;
|
||||
public static int saltLength = 40;
|
||||
|
||||
private static String ivDelimiter = "fA=="; // "|" base64 encoded
|
||||
private static int iterationCount = 1024;
|
||||
private static int keyStrength = 256;
|
||||
|
||||
public static String PUBLIC_KEY = "PUBLIC_KEY";
|
||||
public static String PRIVATE_KEY = "PRIVATE_KEY";
|
||||
public static String AES_CIPHER = "AES/GCM/NoPadding";
|
||||
public static String RSA_CIPHER = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
|
||||
private static String AES_CIPHER = "AES/GCM/NoPadding";
|
||||
private static String RSA_CIPHER = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
|
||||
|
||||
/*
|
||||
JSON
|
||||
|
@ -267,7 +268,7 @@ public class EncryptionUtils {
|
|||
/**
|
||||
* @param ocFile file do crypt
|
||||
* @param encryptionKeyBytes key, either from metadata or {@link EncryptionUtils#generateKey()}
|
||||
* @param iv initialization vector, either from metadata or {@link EncryptionUtils#generateIV()}
|
||||
* @param iv initialization vector, either from metadata or {@link EncryptionUtils#randomBytes(int)}
|
||||
* @return encryptedFile with encryptedBytes and authenticationTag
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
|
@ -283,7 +284,7 @@ public class EncryptionUtils {
|
|||
/**
|
||||
* @param file file do crypt
|
||||
* @param encryptionKeyBytes key, either from metadata or {@link EncryptionUtils#generateKey()}
|
||||
* @param iv initialization vector, either from metadata or {@link EncryptionUtils#generateIV()}
|
||||
* @param iv initialization vector, either from metadata or {@link EncryptionUtils#randomBytes(int)}
|
||||
* @return encryptedFile with encryptedBytes and authenticationTag
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
|
@ -437,7 +438,7 @@ public class EncryptionUtils {
|
|||
CertificateException {
|
||||
|
||||
Cipher cipher = Cipher.getInstance(AES_CIPHER);
|
||||
byte[] iv = generateIV();
|
||||
byte[] iv = randomBytes(ivLength);
|
||||
|
||||
Key key = new SecretKeySpec(encryptionKeyBytes, "AES");
|
||||
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
|
||||
|
@ -500,6 +501,7 @@ public class EncryptionUtils {
|
|||
Cipher cipher = Cipher.getInstance(AES_CIPHER);
|
||||
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
||||
byte[] salt = randomBytes(saltLength);
|
||||
KeySpec spec = new PBEKeySpec(keyPhrase.toCharArray(), salt, iterationCount, keyStrength);
|
||||
SecretKey tmp = factory.generateSecret(spec);
|
||||
SecretKeySpec key = new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||
|
@ -510,9 +512,10 @@ public class EncryptionUtils {
|
|||
|
||||
byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
|
||||
String encodedIV = encodeBytesToBase64String(iv);
|
||||
String encodedSalt = encodeBytesToBase64String(salt);
|
||||
String encodedEncryptedBytes = encodeBytesToBase64String(encrypted);
|
||||
|
||||
return encodedEncryptedBytes + ivDelimiter + encodedIV;
|
||||
return encodedEncryptedBytes + ivDelimiter + encodedIV + ivDelimiter + encodedSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -526,19 +529,21 @@ public class EncryptionUtils {
|
|||
public static String decryptPrivateKey(String privateKey, String keyPhrase) throws NoSuchPaddingException,
|
||||
NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, BadPaddingException,
|
||||
IllegalBlockSizeException, InvalidKeySpecException, InvalidAlgorithmParameterException {
|
||||
Cipher cipher = Cipher.getInstance(AES_CIPHER);
|
||||
|
||||
// split up iv, salt
|
||||
String[] strings = privateKey.split(ivDelimiter);
|
||||
String realPrivateKey = strings[0];
|
||||
byte[] iv = decodeStringToBase64Bytes(strings[1]);
|
||||
byte[] salt = decodeStringToBase64Bytes(strings[2]);
|
||||
|
||||
Cipher cipher = Cipher.getInstance(AES_CIPHER);
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
||||
KeySpec spec = new PBEKeySpec(keyPhrase.toCharArray(), salt, iterationCount, keyStrength);
|
||||
SecretKey tmp = factory.generateSecret(spec);
|
||||
SecretKeySpec key = new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||
|
||||
// handle private key
|
||||
String[] strings = privateKey.split(ivDelimiter);
|
||||
String realPrivateKey = strings[0];
|
||||
String iv = strings[1];
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(decodeStringToBase64Bytes(iv)));
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
|
||||
byte[] bytes = decodeStringToBase64Bytes(realPrivateKey);
|
||||
byte[] decrypted = cipher.doFinal(bytes);
|
||||
|
@ -625,9 +630,9 @@ public class EncryptionUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static byte[] generateIV() {
|
||||
public static byte[] randomBytes(int size) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
final byte[] iv = new byte[16];
|
||||
final byte[] iv = new byte[size];
|
||||
random.nextBytes(iv);
|
||||
|
||||
return iv;
|
||||
|
|
Loading…
Reference in a new issue