docs: @VisibleForTesting
      KeyStore.PrivateKeyEntry getRSAKeyEntry() throws CryptoException, IncompatibleDeviceException {
          try {
              KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
              keyStore.load(null);
              if (keyStore.containsAlias(KEY_ALIAS)) {
                  //Return existing key
                  return getKeyEntryCompat(keyStore);
              }
  
              Calendar start = Calendar.getInstance();
              Calendar end = Calendar.getInstance();
              end.add(Calendar.YEAR, 25);
              AlgorithmParameterSpec spec;
              X500Principal principal = new X500Principal("CN=Auth0.Android,O=Auth0");
  
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                  spec = new KeyGenParameterSpec.Builder(KEY_ALIAS, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
                          .setCertificateSubject(principal)
                          .setCertificateSerialNumber(BigInteger.ONE)
                          .setCertificateNotBefore(start.getTime())
                          .setCertificateNotAfter(end.getTime())
                          .setKeySize(RSA_KEY_SIZE)
                          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                          .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                          .build();
              } else {
                  //Following code is for API 18-22
                  //Generate new RSA KeyPair and save it on the KeyStore
                  KeyPairGeneratorSpec.Builder specBuilder = new KeyPairGeneratorSpec.Builder(context)
                          .setAlias(KEY_ALIAS)
                          .setSubject(principal)
                          .setKeySize(RSA_KEY_SIZE)
                          .setSerialNumber(BigInteger.ONE)
                          .setStartDate(start.getTime())
                          .setEndDate(end.getTime());
  
                  KeyguardManager kManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
                  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                      //The next call can return null when the LockScreen is not configured
                      Intent authIntent = kManager.createConfirmDeviceCredentialIntent(null, null);
                      boolean keyguardEnabled = kManager.isKeyguardSecure() && authIntent != null;
                      if (keyguardEnabled) {
                          //If a ScreenLock is setup, protect this key pair.
                          specBuilder.setEncryptionRequired();
                      }
                  }
                  spec = specBuilder.build();
              }
  
              KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM_RSA, ANDROID_KEY_STORE);
              generator.initialize(spec);
              generator.generateKeyPair();
  
              return getKeyEntryCompat(keyStore);
          } catch (CertificateException | InvalidAlgorithmParameterException | NoSuchProviderException | NoSuchAlgorithmException | KeyStoreException e) {
              /*
               * This exceptions are safe to be ignored:
               *
               * - CertificateException:
               *      Thrown when certificate has expired (25 years..) or couldn't be loaded
               * - KeyStoreException:
               * - NoSuchProviderException:
               *      Thrown when "AndroidKeyStore" is not available. Was introduced on API 18.
               * - NoSuchAlgorithmException:
               *      Thrown when "RSA" algorithm is not available. Was introduced on API 18.
               * - InvalidAlgorithmParameterException:
               *      Thrown if Key Size is other than 512, 768, 1024, 2048, 3072, 4096
               *      or if Padding is other than RSA/ECB/PKCS1Padding, introduced on API 18
               *      or if Block Mode is other than ECB
               *
               * However if any of this exceptions happens to be thrown (OEMs often change their Android distribution source code),
               * all the checks performed in this class wouldn't matter and the device would not be compatible at all with it.
               *
               * Read more in https://developer.android.com/training/articles/keystore#SupportedAlgorithms
               */
              Log.e(TAG, "The device can't generate a new RSA Key pair.", e);
              throw new IncompatibleDeviceException(e);
          } catch (IOException | UnrecoverableEntryException e) {
              /*
               * Any of this exceptions mean the old key pair is somehow corrupted.
               * We can delete both the RSA and the AES keys and let the user retry the operation.
               *
               * - IOException:
               *      Thrown when there is an I/O or format problem with the keystore data.
               * - UnrecoverableEntryException:
               *      Thrown when the key cannot be recovered. Probably because it was invalidated by a Lock Screen change.
               */
              deleteRSAKeys();
              deleteAESKeys();
              throw new CryptoException("The existing RSA key pair could not be recovered and has been deleted. " +
                      "This occasionally happens when the Lock Screen settings are changed. You can safely retry this operation.", e);
          }
      }