SafetyNet for Highest App based Security
Overview
VdoCipher Android SDK integrates Google's SafetyNet protection on versions 1.6.0 and above. This provides additional protection for your videos against the following concerns:
- SafetyNet is protection against application tampering and replay attacks.
- With Safetynet integration enabled, playback on emulators will be blocked by default.
- Safetynet checks for device integrity which should block most rooted devices. Google does not assure that every rooted device can be detected & blocked. Still, this is the highest protection available against rooted devices.
- Blocks duplicate apps. SafetyNet ensures playback is only allowed on apps published by you, and not on any modified APKs. The steps mentioned below will add app certification checks before playback. This will prevent any modified app to play the video.
- You don't need to implement any server-side code for verification of attestation response as defined in Google's SafetyNet docs. That part is already done in our license server.
- SafetyNet can be also be implemented outside our SDK on critical API requests. The steps on this page enforce it in the license exchange that happens before video playback.
To enable SafetyNet protection for your Android apps, you'll need to
- Create OTPs configured with SafetyNet turned on.
- Provide your Google API key using the
VdoInitParams
in the SDK.
For any doubts in the below steps, contact support@vdocipher.com
Steps to add SafetyNet
1. Creating Google API Key
You need an API key from Google to do SafetyNet attestation. To create a key and embed this key, complete the following steps:
- Go to the Library page in the Google APIs Console.
- Search for, and select the Android Device Verification API. The Android Device Verification API dashboard screen appears.
- If the API isn't already enabled, click Enable.
- If the Create credentials button appears, click on it to generate an API key. Otherwise, click the All API credentials drop-down list, then select the API key that's associated with your project that has enabled the Android Device Verification API.
- In the sidebar on the left, click Credentials. Copy the API key that appears.
The default quota allotment (per project) for calling the SafetyNet Attestation API is 10,000 requests per day across your user base. You can monitor your API usage from the Google APIs Console. You can request increased quota by contacting Google. Learn more.
On our SDK, we have implemented a mechanism such that this is only called once per app instance. The API key will not be used again for each playback, unless the app data is cleared.
2. Obtaining apkCertificateDigestSha256
2.1. Obtain the sha256 hex digest of the certificate (debug or release) used to sign the APK before uploading to Google PlayStore.
If you are using your own key to sign the APK, use the keytool
utility
which comes as part of the Android SDK. It will return the sha256 digest in hex
format. (visible under Certificate fingerprints > SHA256)
Note: Commands below are macOS specific. For other OS, use corresponding commands.
keytool -list -v -keystore <path_to_keystore>
If you use App Signing by Google, the fingerprints can be obtained in the Play Console.
2.2. Convert the sha256 fingerprint value obtained in step (1) to base64 encoding. You may use the following command after copying the fingerprint to the clipboard. Or you can use any online tool to do this.
pbpaste | tr -d ':' | xxd -r -p | base64
This command is removing the colon (:
) and converting the hex value to base64.
3. Adding to OTP
OTP creation must be done on your backend
To create an OTP enabled with SafetyNet protection, provide additional parameters androidAttest
and apkCertificateDigestSha256
androidAttest
: the package name of the target APKapkCertificateDigestSha256
: the sha256 digest of the certificate used to sign the APK in base64 encoding.
The above are extra parameters in the JSON body sent to this API along with
ttl
etc. See sample curl request below in next section.
If your backend API is used by players other than the Android app e.g. iOS, web, then you should ensure that the above parameters are added only when the request is coming from the Android app.
4. Adding to VdoInitParams
inside Android app
Specify your API key created in step 1 when creating the VdoInitParams
, using the VdoInitParams.Builder
's setSafetyNetApiKey
method.
After finishing step 1, we recommend testing the SafetyNet implementation on the debug APK first, on your local test devices and emulators. For this, you need to use the debug signing certificate. In step 2, use the debug keystore path in the keytool command (usually .android/debug.keystore
).
VdoInitParams vdoParams = new VdoInitParams.Builder()
.setOtp(...)
.setPlaybackInfo(...)
.setSafetyNetApiKey("______________")
.build();
To integrate safetynet for downloaded videos, specify your API key created in step 1 when creating the DownloadRequest
, using the DownloadRequest.Builder
's setSafetyNetApiKey
method.
For testing locally, you can create SafetyNet-enabled OTPs using curl with the additional androidAttest
and apkCertificateDigestSha256
:
curl -X POST https://www.vdocipher.com/api/videos/$videoId>/otp \
-H 'Accept: application/json' \
-H 'Authorization: Apisecret <your-api-secret>' \
-H 'Content-Type: application/json' \
-d '{"ttl": 300, "androidAttest": "your.package.name", "apkCertificateDigestSha256": "<base64-encoding-of-sha256-digest-of-signing-certificate>"}'
Above code is only for development purposes.
- The high
ttl
value above is only for testing. Keep this value very low for production. - You must use the release certificate's sha256 digest to create the OTP on your backend.
Recommended workflow for adding SafetyNet
Below is a flowchart for how the final workflow should look like.
Troubleshooting associated with SafetyNet
Below are the possible error that can occur when using SafetyNet along with steps to resolve it.
Code | Message | Meaning & Resolution |
---|---|---|
2029 | Attestation not received | setSafetyNetApiKey is not set correctly in the VdoInitParams. Check step 4 above. |
2030 | Internal error | This is an internal error. Please contact support. |
2031 | package name mismatch | The package name in the verification response from the Google Play Store does not match the package name provided in OTP. |
2032 | Nonce check failed | Repeated request with same nonce. Can be caused by replay attack. |
2033 | device checks failed | Integrity failed. Can be caused by tampering. |
2034 | device checks failed | cts match failed. Can be caused by tampering. |
2035 | Nonce check failed | Incorrect nonce. Can be caused by replay attack. |
2036 | device verification failed | Incorrect re-verify attestation string. Can be caused by tampering. |
2037 | App could not be verified | apkDigestSha256 verification failed |
2038 | App could not be verified | apkCertificateDigestSha256 verification failed |
2039 | Internal error | This is an internal error. Please contact support. |
Handling errors
SafetyNet is a security feature provided by Google to authenticate the app software against tampering. Verification of the app's signature is done by APIs provided by the Google Play Store and implemented by Manufacturer. There will be few devices not able to verify the app's signature. This will be rare but it is possible. It is also possible that the same device model will work for one user but not for another user.
It is recommended to keep a list of users on your backend database which are exempt from the verification. If a particular user's device is consistently giving errors, you can set this user to be exempt. This can be done by keeping a user-attribute associated with the user in your backend.
This way, when you know that a valid user is trying to access your app, they still can get it working after a call to your support team.
Check the third decision box in the above flow-chart for how to implement this logic.