Zum Inhalt

App Security

App Security

Permission management

To make your BlueID-powered Android app work correctly, you have to declare at least these permissions in your manifest:

  • android.permission.INTERNET: required to initialize and synchronize a BlueID Mobile Device

  • android.permission.BLUETOOTH: required to connect to Bluetooth devices

  • android.permission.BLUETOOTH_ADMIN: required to discover Bluetooth devices

  • android.permission.ACCESS_FINE_LOCATION: required to scan for Bluetooth devices

Starting with Android 6.0 (Marshmallow), permissions marked with dangerous are not directly granted during app installation, but need to get explicitly approved by the user instead. Moreover, the user can dynamically revoke those permissions. From the permissions above, this only applies to ACCESS_FINE_LOCATION. Because of that, you have to declare them in your manifest and additionally you have to make sure that they are granted at runtime, preferably before executing a command. Please refer to the official Android documentation to get detailed information about Android's permission management.

Furthermore, new since Android 6.0 (Marshmallow), it is required to have the location feature activated in order to scan for Bluetooth low energy devices. To be more precise, this applies if your app is running on an Android device with Android 6.0 or higher and the targetSdkVersion specified in the app manifest is API level 23 or above.

If you target an API level lower than 29 (Android 10, Q), ACCESS_COARSE_LOCATION is enough. But if you target a higher API level, you must declare ACCESS_FINE_LOCATION instead.

The BlueID SDK for Android includes a helper class that determines during runtime which permissions are missing and which device features must be switched on before a BlueID command can be executed. A detailed description of this helper class can be found in the API documentation. Additionally the example client, which is part of the BlueID SDK for Android and available in the Download Area, includes example code how to use this class and how to request permissions from the user during runtime.

Third party crypto providers
General information

BlueID recommends not to use third party crypto providers as they aren't tested in our development environment. Also, BlueID makes use of the hardware-backed AndroidKeyStore and a third party crypto provider can easily break it if they were not aware of this. Android issue #123686423 describes the behavior and its impacts.


SpongyCastle crypto provider isn't compatible with our SDK. Since SpongyCastle may be included in an application as a transient dependency of other frameworks and excluding it could be unavoidable in some situations, BlueID developed a feature to support the coexistence of Android SDK with SpongyCastle from SDK for Android 3.4 and higher.

Technical background

The reason for issues with SC is that its developers recommend to install it as first crypto provider in the system. While this is not an issue on its own, SC claims that it supports all types of keys, including the ones residing in the AndroidKeyStore which we use for security reasons. But as SC is a pure software solution, it needs to work with the raw contents of the private key but is unable to retrieve it because it's in a secure enclave. While initializing an MD instance works, it fails when you want to execute a command.

How it works

When the SpongyCastle coexistence feature is enabled, BlueID Android SDK moves the SpongyCastle provider to the end of the provider list before any cryptographic operation and moves it back to the original position afterwards. This works perfectly on a range of phones we tested, but we cannot guarantee that it works under all circumstances due to the broad range of apps and solutions. This feature may have some side effects which did not appear during our testing.

How to enable it

In order to enable this feature, a System property has to be in place before you instantiate the BlueID SDK via the SdkForAndroid class. This is done by calling:

System.setProperty("net.blueid.sdk.ENABLE\_SPONGYCASTLE\_COEXISTENCE", "true");

This feature isn't enabled by default as BlueID doesn't recommend the usage of third party crypto providers and may have side effects which didn't appear during our validation and testing.

Keychain security level

We offer different keychain security levels to store your BlueID related data:

  • BlueIDKeychainSecurityLevelHigh: This level is used by default and makes sure that the BlueID related data is not accessible while the iPhone is locked

  • BlueIDKeychainSecurityLevelBackgroundTasksEnabled: This level is mandatory if you need to access the BlueIDMobileDevice instance while the iPhone is locked, e.g. for periodic synchronizing as part of a background fetch or for showing the screen with the closest BlueID Secured Object by usage of iBeacons

You can specify the keychain security level during initialization of the SDK:


[[BlueIDMobileDevice sharedInstance]
  initializeWithInitParametersBlock:^(BlueIDMobileDeviceInitParameters *params)
  params.apiKey = API_KEY;
  params.trustCenterHostName = [params defaultProductionTrustCenterHostName];
  params.keychainSecurityLevel = BlueIDKeychainSecurityLevelBackgroundTasksEnabled;
completionHandler:^(NSString *deviceId, NSError *error)
  // store deviceId and send it to your server to map it to an entity


BlueIDMobileDevice.sharedInstance()?.initialize(initParametersBlock: { (params: BlueIDMobileDeviceInitParameters?) -> Void in
                params?.apiKey = API_KEY
                params?.trustCenterHostName = params?.defaultIntegrationTrustCenterHostName()
                params?.keychainSecurityLevel = .backgroundTasksEnabled
            }, completionHandler: { (deviceId: String?, error: Error?) -> Void in                     
                // store deviceId and send it to your server to map it to an entity

For further information about the keychain security level take a look at our BlueID Keychain Security Level best practices. Note that BlueIDKeychainSecurityLevelHigh is activated by default.