Skip to main content
Version: 2.4.x.x

FacetID Calculation

This section provides help in calculating the Access App facet ID. The FacetID is part of the required backend configuration.

Additional Information

The nevisAdmin4 documentation offers information on where to configure the FacetID in the nevisFIDO Setup.

Chapter FIDO UAF Configuration of the nevisFIDO Reference Guide provides detailed configuration information.

iOS

In the iOS case, the FacetID must be the BundleID URI of the application:

iOS Facet ID
ios:bundle-id:<ios-bundle-id-of-app>

Android

To get the correct FacetID for the Android app, install the app on a device, and extract the facetID from the hidden advanced settings menu.

According to the FIDO UAF 1.1 Specifications, the FacetID for Android is a Base64 encoded hash value based on the SPK signing certificate:

Android Facet ID
android:apk-key-hash:HASH_VALUE
Wrong Example in FIDO UAF Documentation!

The example in the FIDO UAF 1.1 specification "EXAMPLE 1: Computing an APK signing certificate hash" is wrong! It will lead to a wrong hash being calculated.

  • The filtering of the error output is wrong (correct: "2>", incorrect: "&>2").
  • The keystore (or key) password must be provided if the keystore is password protected.
Functional Adaption

The Nevis Access App uses SHA-256 to calculate the Facet ID hash. For additional information, refer to the chapter Functional Adaptions of the FIDO UAF Specification.

Hash Calculation

caution

If Google Play store Play App Signing is used, you cannot use the tool to calculate the FacetID, as the certificate used by Google is different, and thus leads to a different FacetID. In this case, install the app on an Android device, and extract the facetID from the hidden advanced settings menu.

We recommend using the calculateFacetId.sh script to calculate the FacetID. This script checks the output of the keytool command logs error to stdout in case an error occurs.

calculateFacetId.sh Script - Click to Expand

calculateFacetId.sh Script
#!/bin/bash

usage()
{
echo "usage: calculateFacetId.sh --keystore <path-to-apk-signing-keystore> --key-alias <alias-of-entry> [--keystore-password <keystore-password>]"
}

keystore=''
keystore_password=''
key_alias=''

while test $# -gt 0
do
case "$1" in
--keystore)
keystore=$2
;;
--key-alias)
key_alias=$2
;;
--keystore-password)
keystore_password=$2
;;
--*)
echo "bad option $1"
usage
exit 0
;;
esac
shift
done

if [ -z $keystore ] || [ -z $key_alias ]
then
usage
exit
fi

echo "-----------------------------------"
echo "Keystore: $keystore"
echo "Key alias: $key_alias"
echo "Keystore password is $(if [ -z $keystore_password ]; then echo "NOT "; fi)provided"
echo "-----------------------------------"

keystore_password_argument=$(if [ ! -z $keystore_password ]; then echo "-storepass $keystore_password"; fi)
command="keytool -keystore $keystore -alias $key_alias -exportcert $keystore_password_argument"

[ -f "$keystore" ] || {
echo "Keystore file ($keystore) doesn't exist."
echo "-----------------------------------"
exit 0
}

eval $command 2> /dev/null > cert.crt <&-

if [[ $(cat cert.crt) != *error* ]];
then
facet_id=$(cat cert.crt | openssl sha256 -binary | openssl base64 | sed 's/=//g')
echo "Calculated FacetID:"
echo "android:apk-key-hash:$facet_id"
echo "-----------------------------------"
else
echo "Error in calculation: $(cat cert.crt)"
echo "-----------------------------------"
fi

rm cert.crt

The script

  • exports the signing certificate in DER format,
  • base64 encodes the hash of it, and
  • trims the '=' sign.
danger

The script temporarily exports the certificate into a file (cert.crt) into the current directory. Therefore, the current user must have write permission in the current folder.

Script Usage

danger

If the keystore is protected with a password, supply the option --keystore-password to prevent the execution from resulting in an error (see the code snippet further below; the option is part of the first code section).

If no errors occur, the scripts reports the whole FacetID as output:

> ./calculateFacetId.sh --keystore <path-to-apk-signing-keystore> --key-alias <alias-of-entry> --keystore-password <keystore-password>
-----------------------------------
Keystore: <path-to-apk-signing-keystore>
Key alias: <alias-of-entry>
Keystore password is provided
-----------------------------------
Calculated FacetID:
android:apk-key-hash:<calculated_hash>
-----------------------------------

In case of an error, the output shows the occurred error message:

> ./calculateFacetId.sh --keystore <path-to-apk-signing-keystore> --key-alias <alias-of-entry> --keystore-password <wrong-keystore-password>
-----------------------------------
Keystore: <path-to-apk-signing-keystore>
Key alias: <alias-of-entry>
Keystore password is provided
-----------------------------------
Error in calculation: keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect
-----------------------------------

Manual FacetID Calculations

caution

We recommend using the scripts below only for verification purposes, to check that the hash generated by the calculateFacetId.sh script is correct.

Keystore without Password

In case of a keystore without password, you can use the computing method example included in the FIDO UAF 1.1 Specifications. Considering the warning mentioned above, the corrected method is the following:

keytool -keystore <path-to-apk-signing-keystore> \
-alias <alias-of-entry> \
-exportcert 2> /dev/null | \
openssl sha256 -binary | openssl base64 | sed 's/=//g'
Keystore with Password Containing Key

In case of a keystore with a password that contains the key, provide the keystore password (-storepass) to export the signing certificate:

keytool -keystore <path-to-apk-signing-keystore> \
-alias <alias-of-entry> \
-exportcert \
-storepass <keystore-password> 2> /dev/null | \
openssl sha256 -binary | openssl base64 | sed 's/=//g'