Replace SpongyCastle with BouncyCastle

SpongyCastle is a fork of BouncyCastle. We originally used this fork to 1) have
access to scrypt and 2) prevent a package name collision with the bundled
BouncyCastle. We don't actually need to use the fork anymore, because the
package name of the bundled BouncyCastle was changed in Android. SpongyCastle
has also gotten quite outdated in recent years.

The built-in version of BouncyCastle is replaced with the one bundled with the
app at runtime, so that we have a recent version even on older Android versions.

This also updates Gradle and the Gradle Android plugin, to fix a build error I
was running into when I added the dependency to BouncyCastle.
This commit is contained in:
Alexander Bakker 2019-05-30 13:58:10 +02:00
parent b4d2b6b113
commit 3c887d8392
5 changed files with 22 additions and 3 deletions

View file

@ -2,7 +2,8 @@ package com.beemdevelopment.aegis.crypto;
import android.os.Build;
import org.spongycastle.crypto.generators.SCrypt;
import org.bouncycastle.crypto.generators.SCrypt;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -12,7 +13,9 @@ import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
@ -36,6 +39,15 @@ public class CryptoUtils {
public static final int CRYPTO_SCRYPT_r = 8;
public static final int CRYPTO_SCRYPT_p = 1;
// replace the BC provider from Android with the one bundled with the app
static {
final Provider provider = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
if (provider != null && !provider.getClass().equals(BouncyCastleProvider.class)) {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
Security.addProvider(new BouncyCastleProvider());
}
}
public static SecretKey deriveKey(byte[] input, SCryptParameters params) {
byte[] keyBytes = SCrypt.generate(input, params.getSalt(), params.getN(), params.getR(), params.getP(), CRYPTO_AEAD_KEY_SIZE);
return new SecretKeySpec(keyBytes, 0, keyBytes.length, "AES");