Java Code Examples for android.security.keystore.KeyGenParameterSpec#Builder

The following examples show how to use android.security.keystore.KeyGenParameterSpec#Builder . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CipherStorageKeystoreAesCbc.java    From react-native-keychain with MIT License 6 votes vote down vote up
/** Get encryption algorithm specification builder instance. */
@NonNull
@Override
protected KeyGenParameterSpec.Builder getKeyGenSpecBuilder(@NonNull final String alias)
  throws GeneralSecurityException {
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
    throw new KeyStoreAccessException("Unsupported API" + Build.VERSION.SDK_INT + " version detected.");
  }

  final int purposes = KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT;

  return new KeyGenParameterSpec.Builder(alias, purposes)
    .setBlockModes(BLOCK_MODE_CBC)
    .setEncryptionPaddings(PADDING_PKCS7)
    .setRandomizedEncryptionRequired(true)
    .setKeySize(ENCRYPTION_KEY_SIZE);
}
 
Example 2
Source File: CryptUtil.java    From PowerFileExplorer with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Gets a secret key from Android key store.
 * If no key has been generated with a given alias then generate a new one
 * @return
 * @throws KeyStoreException
 * @throws CertificateException
 * @throws NoSuchAlgorithmException
 * @throws IOException
 * @throws NoSuchProviderException
 * @throws InvalidAlgorithmParameterException
 * @throws UnrecoverableKeyException
 */
@RequiresApi(api = Build.VERSION_CODES.M)
private static Key getSecretKey() throws KeyStoreException, CertificateException,
        NoSuchAlgorithmException, IOException, NoSuchProviderException,
        InvalidAlgorithmParameterException,
        UnrecoverableKeyException {

    KeyStore keyStore = KeyStore.getInstance(KEY_STORE_ANDROID);
    keyStore.load(null);

    if (!keyStore.containsAlias(KEY_ALIAS_AMAZE)) {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE_ANDROID);

        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(KEY_ALIAS_AMAZE,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);
        builder.setBlockModes(KeyProperties.BLOCK_MODE_GCM);
        builder.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);
        builder.setRandomizedEncryptionRequired(false);

        keyGenerator.init(builder.build());
        return keyGenerator.generateKey();
    } else {
        return keyStore.getKey(KEY_ALIAS_AMAZE, null);
    }
}
 
Example 3
Source File: MainActivity.java    From android-biometricprompt with Apache License 2.0 6 votes vote down vote up
private KeyPair generateKeyPair(String keyName, boolean invalidatedByBiometricEnrollment) throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");

    KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
            KeyProperties.PURPOSE_SIGN)
            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
            .setDigests(KeyProperties.DIGEST_SHA256,
                    KeyProperties.DIGEST_SHA384,
                    KeyProperties.DIGEST_SHA512)
            // Require the user to authenticate with a biometric to authorize every use of the key
            .setUserAuthenticationRequired(true);

    // Generated keys will be invalidated if the biometric templates are added more to user device
    if (Build.VERSION.SDK_INT >= 24) {
        builder.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
    }

    keyPairGenerator.initialize(builder.build());

    return keyPairGenerator.generateKeyPair();
}
 
Example 4
Source File: TestActivity.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
public boolean createKeyPair() {
    try {
        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
                .setDigests(KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA256)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                .setKeySize(2048);
        builder.setIsStrongBoxBacked(true);
        builder.setInvalidatedByBiometricEnrollment(true);
        builder.setUserAuthenticationRequired(true);

        keyPairGenerator.initialize(builder.build());
        keyPairGenerator.generateKeyPair();
        return true;
    } catch (InvalidAlgorithmParameterException e) {
        return false;
    }
}
 
Example 5
Source File: MainActivity.java    From Study_Android_Demo with Apache License 2.0 6 votes vote down vote up
@TargetApi(23)
private void initKey() {
    try {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,
                KeyProperties.PURPOSE_ENCRYPT |
                        KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                .setUserAuthenticationRequired(true)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
        keyGenerator.init(builder.build());
        keyGenerator.generateKey();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
 
Example 6
Source File: AuthKeyGenerator.java    From sensorhub-cloud-iot with Apache License 2.0 6 votes vote down vote up
/**
 * Generate a new key pair entry in the Android Keystore by using the KeyPairGenerator API.
 * This creates both a KeyPair and a self-signed certificate, both with the same alias,
 * using the {@link #keyAlgorithm} provided.
 */
private void generateAuthenticationKey() throws GeneralSecurityException {
    KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgorithm, keystoreName);
    KeyGenParameterSpec.Builder specBuilder =
            new KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_SIGN)
            .setCertificateSubject(new X500Principal("CN=unused"))
            .setDigests(KeyProperties.DIGEST_SHA256);

    if (keyAlgorithm.equals(KeyProperties.KEY_ALGORITHM_RSA)) {
        specBuilder.setKeySize(KEY_SIZE_RSA)
                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
    } else if (keyAlgorithm.equals(KeyProperties.KEY_ALGORITHM_EC)) {
        specBuilder.setKeySize(KEY_SIZE_EC);
    }
    kpg.initialize(specBuilder.build());

    kpg.generateKeyPair();
}
 
Example 7
Source File: SensitiveDataPostApi23.java    From android-java-connect-rest-sample with MIT License 6 votes vote down vote up
protected SecretKey generateKey() {
    SecretKey key = null;
    try {
        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
                getKeyAlias(),
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);

        KeyGenParameterSpec keySpec = builder
                .setKeySize(CIPHER_KEY_LENGHT)
                .setBlockModes(CIPHER_BLOCKS)
                .setEncryptionPaddings(CIPHER_PADDING)
                .setRandomizedEncryptionRequired(false) //FIXME: set to true because we should be using IND-CPA but this means that a IV has to be store per token (less generic than i though)
                .setUserAuthenticationRequired(isKeyPinRequired())
                .setUserAuthenticationValidityDurationSeconds(getKeyPinDuration())
                .build();

        KeyGenerator  kg = KeyGenerator.getInstance(CIPHER_ALGO, KEYSTORE_TYPE);
        kg.init(keySpec);
        key = kg.generateKey();
    } catch (InvalidAlgorithmParameterException | NoSuchProviderException | NoSuchAlgorithmException e) {
        Log.e(TAG, "Couldn't generate secret key", e);
    }
    return key;
}
 
Example 8
Source File: FingerprintActivity.java    From AndroidSamples with Apache License 2.0 6 votes vote down vote up
/**
 * Generate NIST P-256 EC Key pair for signing and verification
 *
 * @param keyName
 * @param invalidatedByBiometricEnrollment
 * @return
 * @throws Exception
 */
@TargetApi(Build.VERSION_CODES.P)
private KeyPair generateKeyPair(String keyName, boolean invalidatedByBiometricEnrollment) throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");

    KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
            KeyProperties.PURPOSE_SIGN)
            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
            .setDigests(KeyProperties.DIGEST_SHA256,
                    KeyProperties.DIGEST_SHA384,
                    KeyProperties.DIGEST_SHA512)
            // Require the user to authenticate with a biometric to authorize every use of the key
            .setUserAuthenticationRequired(true)
            .setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);

    keyPairGenerator.initialize(builder.build());

    return keyPairGenerator.generateKeyPair();
}
 
Example 9
Source File: FingerprintDialog.java    From journaldev with MIT License 6 votes vote down vote up
public void createKey(String keyName) {
    // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
    // for your flow. Use of keys is necessary if you need to know if the set of
    // enrolled fingerprints has changed.
    try {
        mKeyStore.load(null);
        // Set the alias of the entry in Android KeyStore where the key will appear
        // and the constrains (purposes) in the constructor of the Builder

        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
                KeyProperties.PURPOSE_ENCRYPT |
                        KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                // Require the user to authenticate with a fingerprint to authorize every use
                // of the key
                .setUserAuthenticationRequired(true)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);

        mKeyGenerator.init(builder.build());
        mKeyGenerator.generateKey();
    } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
            | CertificateException | IOException e) {
        throw new RuntimeException(e);
    }
}
 
Example 10
Source File: RNSensitiveInfoModule.java    From react-native-sensitive-info with MIT License 5 votes vote down vote up
private void prepareKey() throws Exception {
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
        return;
    }
    KeyGenerator keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE_PROVIDER);

    KeyGenParameterSpec.Builder builder = null;
    builder = new KeyGenParameterSpec.Builder(
            KEY_ALIAS_AES,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);

    builder.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setKeySize(256)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            // forces user authentication with fingerprint
            .setUserAuthenticationRequired(true);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        try {
            builder.setInvalidatedByBiometricEnrollment(invalidateEnrollment);
        } catch (Exception e) {
            Log.d("RNSensitiveInfo", "Error setting setInvalidatedByBiometricEnrollment: " + e.getMessage());
        }
    }

    keyGenerator.init(builder.build());
    keyGenerator.generateKey();
}
 
Example 11
Source File: CipherProvider.java    From RxFingerprint with Apache License 2.0 5 votes vote down vote up
@NonNull
@TargetApi(Build.VERSION_CODES.M)
static KeyGenParameterSpec.Builder getKeyGenParameterSpecBuilder(String keyName, String blockModes, String encryptionPaddings, boolean invalidatedByBiometricEnrollment) {
	KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
			KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
			.setBlockModes(blockModes)
			.setUserAuthenticationRequired(true)
			.setEncryptionPaddings(encryptionPaddings);
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
		builder.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
	}
	return builder;
}
 
Example 12
Source File: KeyStoreHelper.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
@RequiresApi(Build.VERSION_CODES.M)
public static SecretKey createKeyStoreEntryHmac() {
  try {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_HMAC_SHA256, ANDROID_KEY_STORE);

    KeyGenParameterSpec.Builder keySpecBuilder = new KeyGenParameterSpec.Builder(KEY_ALIAS_HMAC, KeyProperties.PURPOSE_SIGN);
    KeyGenParameterSpec keyGenParameterSpec = keySpecBuilder.build();

    keyGenerator.init(keyGenParameterSpec);

    return keyGenerator.generateKey();
  } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
    throw new AssertionError(e);
  }
}
 
Example 13
Source File: AesCipherFactory.java    From Android-Goldfinger with Apache License 2.0 5 votes vote down vote up
/**
 * Create secure key used to create Cipher.
 *
 * @param key name of the keystore.
 * @return created key, or null if something weird happens.
 * @throws Exception if anything fails, it is handled gracefully.
 */
@Nullable
private Key createKey(@NonNull String key) throws Exception {
    KeyGenParameterSpec.Builder keyGenParamsBuilder =
        new KeyGenParameterSpec.Builder(key, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(isUserAuthRequired());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        keyGenParamsBuilder.setInvalidatedByBiometricEnrollment(isUserAuthRequired());
    }
    keyGenerator.init(keyGenParamsBuilder.build());
    keyGenerator.generateKey();
    return loadKey(key);
}
 
Example 14
Source File: FidoKeystoreAndroidM.java    From UAF with Apache License 2.0 4 votes vote down vote up
@Override
public KeyPair generateKeyPair(String username) {
    Log.d(TAG, "generateKeyPair");

    try {
        String keyId = getKeyId(username);
        Log.d(TAG, "keyId = " + keyId);
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
                keyId,
                KeyProperties.PURPOSE_SIGN)
                .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                .setDigests(KeyProperties.DIGEST_SHA256,
                        KeyProperties.DIGEST_SHA384,
                        KeyProperties.DIGEST_SHA512)
                // Only permit the private key to be used if the user authenticated
                // within the last five minutes.
                .setUserAuthenticationRequired(true);
        if (!isFingerprintAuthAvailable()) {
            // make sure key can be used with PIN if no FP available or supported
            // authenticaton is done via the confirmCredentials() API
            builder = builder.setUserAuthenticationValidityDurationSeconds(KEY_TIMEOUT_SECS);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // XXX this needs to be the real server challenge
            builder = builder.setAttestationChallenge(new byte[16]);
            builder = builder.setInvalidatedByBiometricEnrollment(false);
        }
        keyPairGenerator.initialize(builder.build());

        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        Log.d(TAG, "Generated keypair : " + keyPair);

        KeyStore keyStore = getAndroidKeyStore();
        X509Certificate cert = (X509Certificate) keyStore.getCertificate(keyId);
        Log.d(TAG, "certificate: " + cert);

        return keyPair;
    } catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
    }
}
 
Example 15
Source File: CryptoUtilTest.java    From Auth0.Android with MIT License 4 votes vote down vote up
@RequiresApi(api = Build.VERSION_CODES.M)
@Test
@Config(sdk = 23)
public void shouldCreateRSAKeyPairIfMissingOnAPI23AndUp() throws Exception {
    ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 23);

    PowerMockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(false);
    KeyStore.PrivateKeyEntry expectedEntry = PowerMockito.mock(KeyStore.PrivateKeyEntry.class);
    PowerMockito.when(keyStore.getEntry(KEY_ALIAS, null)).thenReturn(expectedEntry);

    KeyGenParameterSpec spec = PowerMockito.mock(KeyGenParameterSpec.class);
    KeyGenParameterSpec.Builder builder = newKeyGenParameterSpecBuilder(spec);
    PowerMockito.whenNew(KeyGenParameterSpec.Builder.class).withArguments(KEY_ALIAS, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT).thenReturn(builder);

    ArgumentCaptor<X500Principal> principalCaptor = ArgumentCaptor.forClass(X500Principal.class);
    ArgumentCaptor<Date> startDateCaptor = ArgumentCaptor.forClass(Date.class);
    ArgumentCaptor<Date> endDateCaptor = ArgumentCaptor.forClass(Date.class);


    final KeyStore.PrivateKeyEntry entry = cryptoUtil.getRSAKeyEntry();


    Mockito.verify(builder).setKeySize(2048);
    Mockito.verify(builder).setCertificateSubject(principalCaptor.capture());
    Mockito.verify(builder).setCertificateSerialNumber(BigInteger.ONE);
    Mockito.verify(builder).setCertificateNotBefore(startDateCaptor.capture());
    Mockito.verify(builder).setCertificateNotAfter(endDateCaptor.capture());
    Mockito.verify(builder).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
    Mockito.verify(builder).setBlockModes(KeyProperties.BLOCK_MODE_ECB);
    Mockito.verify(keyPairGenerator).initialize(spec);
    Mockito.verify(keyPairGenerator).generateKeyPair();

    assertThat(principalCaptor.getValue(), is(notNullValue()));
    assertThat(principalCaptor.getValue().getName(), is(CERTIFICATE_PRINCIPAL));

    assertThat(startDateCaptor.getValue(), is(notNullValue()));
    long diffMillis = startDateCaptor.getValue().getTime() - new Date().getTime();
    long days = TimeUnit.MILLISECONDS.toDays(diffMillis);
    assertThat(days, is(0L)); //Date is Today

    assertThat(endDateCaptor.getValue(), is(notNullValue()));
    diffMillis = endDateCaptor.getValue().getTime() - new Date().getTime();
    days = TimeUnit.MILLISECONDS.toDays(diffMillis);
    assertThat(days, is(greaterThan(25 * 365L))); //Date more than 25 Years in days

    assertThat(entry, is(expectedEntry));
}
 
Example 16
Source File: CryptoUtilTest.java    From Auth0.Android with MIT License 4 votes vote down vote up
@RequiresApi(api = Build.VERSION_CODES.P)
@Test
@Config(sdk = 28)
public void shouldCreateRSAKeyPairIfMissingOnAPI28AndUp() throws Exception {
    ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 28);

    PowerMockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(false);
    KeyStore.PrivateKeyEntry expectedEntry = PowerMockito.mock(KeyStore.PrivateKeyEntry.class);
    PowerMockito.when(keyStore.getEntry(KEY_ALIAS, null)).thenReturn(expectedEntry);

    KeyGenParameterSpec spec = PowerMockito.mock(KeyGenParameterSpec.class);
    KeyGenParameterSpec.Builder builder = newKeyGenParameterSpecBuilder(spec);
    PowerMockito.whenNew(KeyGenParameterSpec.Builder.class).withArguments(KEY_ALIAS, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT).thenReturn(builder);

    ArgumentCaptor<X500Principal> principalCaptor = ArgumentCaptor.forClass(X500Principal.class);
    ArgumentCaptor<Date> startDateCaptor = ArgumentCaptor.forClass(Date.class);
    ArgumentCaptor<Date> endDateCaptor = ArgumentCaptor.forClass(Date.class);


    final KeyStore.PrivateKeyEntry entry = cryptoUtil.getRSAKeyEntry();

    Mockito.verify(builder).setKeySize(2048);
    Mockito.verify(builder).setCertificateSubject(principalCaptor.capture());
    Mockito.verify(builder).setCertificateSerialNumber(BigInteger.ONE);
    Mockito.verify(builder).setCertificateNotBefore(startDateCaptor.capture());
    Mockito.verify(builder).setCertificateNotAfter(endDateCaptor.capture());
    Mockito.verify(builder).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
    Mockito.verify(builder).setBlockModes(KeyProperties.BLOCK_MODE_ECB);
    Mockito.verify(keyPairGenerator).initialize(spec);
    Mockito.verify(keyPairGenerator).generateKeyPair();

    assertThat(principalCaptor.getValue(), is(notNullValue()));
    assertThat(principalCaptor.getValue().getName(), is(CERTIFICATE_PRINCIPAL));

    assertThat(startDateCaptor.getValue(), is(notNullValue()));
    long diffMillis = startDateCaptor.getValue().getTime() - new Date().getTime();
    long days = TimeUnit.MILLISECONDS.toDays(diffMillis);
    assertThat(days, is(0L)); //Date is Today

    assertThat(endDateCaptor.getValue(), is(notNullValue()));
    diffMillis = endDateCaptor.getValue().getTime() - new Date().getTime();
    days = TimeUnit.MILLISECONDS.toDays(diffMillis);
    assertThat(days, is(greaterThan(25 * 365L))); //Date more than 25 Years in days

    assertThat(entry, is(expectedEntry));
}
 
Example 17
Source File: CryptoUtilTest.java    From Auth0.Android with MIT License 4 votes vote down vote up
@RequiresApi(api = Build.VERSION_CODES.P)
@Test
@Config(sdk = 28)
public void shouldCreateNewRSAKeyPairWhenExistingRSAKeyPairCannotBeRebuiltOnAPI28AndUp() throws Exception {
    ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 28);
    PrivateKey privateKey = PowerMockito.mock(PrivateKey.class);

    //This is required to trigger the fallback when alias is present but key is not
    PowerMockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(true);
    PowerMockito.when(keyStore.getKey(KEY_ALIAS, null)).thenReturn(privateKey).thenReturn(null);
    PowerMockito.when(keyStore.getCertificate(KEY_ALIAS)).thenReturn(null);
    //This is required to trigger finding the key after generating it
    KeyStore.PrivateKeyEntry expectedEntry = PowerMockito.mock(KeyStore.PrivateKeyEntry.class);
    PowerMockito.when(keyStore.getEntry(KEY_ALIAS, null)).thenReturn(expectedEntry);

    //Tests no instantiation of PrivateKeyEntry
    PowerMockito.verifyZeroInteractions(KeyStore.PrivateKeyEntry.class);

    //Creation assertion
    KeyGenParameterSpec spec = PowerMockito.mock(KeyGenParameterSpec.class);
    KeyGenParameterSpec.Builder builder = newKeyGenParameterSpecBuilder(spec);
    PowerMockito.whenNew(KeyGenParameterSpec.Builder.class).withArguments(KEY_ALIAS, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT).thenReturn(builder);

    ArgumentCaptor<X500Principal> principalCaptor = ArgumentCaptor.forClass(X500Principal.class);
    ArgumentCaptor<Date> startDateCaptor = ArgumentCaptor.forClass(Date.class);
    ArgumentCaptor<Date> endDateCaptor = ArgumentCaptor.forClass(Date.class);


    final KeyStore.PrivateKeyEntry entry = cryptoUtil.getRSAKeyEntry();

    Mockito.verify(builder).setKeySize(2048);
    Mockito.verify(builder).setCertificateSubject(principalCaptor.capture());
    Mockito.verify(builder).setCertificateSerialNumber(BigInteger.ONE);
    Mockito.verify(builder).setCertificateNotBefore(startDateCaptor.capture());
    Mockito.verify(builder).setCertificateNotAfter(endDateCaptor.capture());
    Mockito.verify(builder).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
    Mockito.verify(builder).setBlockModes(KeyProperties.BLOCK_MODE_ECB);
    Mockito.verify(keyPairGenerator).initialize(spec);
    Mockito.verify(keyPairGenerator).generateKeyPair();

    assertThat(principalCaptor.getValue(), is(notNullValue()));
    assertThat(principalCaptor.getValue().getName(), is(CERTIFICATE_PRINCIPAL));

    assertThat(startDateCaptor.getValue(), is(notNullValue()));
    long diffMillis = startDateCaptor.getValue().getTime() - new Date().getTime();
    long days = TimeUnit.MILLISECONDS.toDays(diffMillis);
    assertThat(days, is(0L)); //Date is Today

    assertThat(endDateCaptor.getValue(), is(notNullValue()));
    diffMillis = endDateCaptor.getValue().getTime() - new Date().getTime();
    days = TimeUnit.MILLISECONDS.toDays(diffMillis);
    assertThat(days, is(greaterThan(25 * 365L))); //Date more than 25 Years in days

    assertThat(entry, is(expectedEntry));
}
 
Example 18
Source File: EncryptionManagerAPI23.java    From samples-android with Apache License 2.0 4 votes vote down vote up
@Override
boolean generateKeyPair(Context context, KeyPairGenerator generator, String keyAlias,
                        int keySize, String encryptionPadding, String blockMode,
                        boolean isStrongBoxBacked, @Nullable byte[] seed) {
    try {
        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyAlias,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setKeySize(keySize)
                .setBlockModes(blockMode)
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .setEncryptionPaddings(encryptionPadding)
                .setUserAuthenticationRequired(mIsAuthenticateUserRequired)
                .setUserAuthenticationValidityDurationSeconds(mValidityDurationSeconds);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // If fingerprints list changed or will be empty
            // current keys are invalid.
            // This option doesn't work, because we set
            // UserAuthenticationValidityDurationSeconds parameter and this option works only
            // if this parameter set to not positive
            // builder.setInvalidatedByBiometricEnrollment(mIsAuthenticateUserRequired);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            // In Android P was introduced new way to persist keystore - StrongBox
            // If device doesn't support StrongBox, it will use TEE implementation if present.
            builder.setIsStrongBoxBacked(isStrongBoxBacked);
        }

        if (seed != null && seed.length > 0) {
            SecureRandom random = new SecureRandom(seed);
            generator.initialize(builder.build(), random);
        } else {
            generator.initialize(builder.build());
        }

        return true;
    } catch (InvalidAlgorithmParameterException e) {
        Log.e(TAG, "initialize KeyPairGenerator: ", e);
    }
    return false;
}
 
Example 19
Source File: CipherStorageBase.java    From react-native-keychain with MIT License 4 votes vote down vote up
/** Get encryption algorithm specification builder instance. */
@NonNull
protected abstract KeyGenParameterSpec.Builder getKeyGenSpecBuilder(@NonNull final String alias)
  throws GeneralSecurityException;
 
Example 20
Source File: CipherStorageFacebookConceal.java    From react-native-keychain with MIT License 4 votes vote down vote up
@NonNull
@Override
protected KeyGenParameterSpec.Builder getKeyGenSpecBuilder(@NonNull final String alias)
  throws GeneralSecurityException {
  throw new CryptoFailedException("Not designed for a call");
}