Product Documentation

NOTE: Learn more about the Policy Module here.

 

FIDO-ERR-2001: FIDO 2 Error Message : {0} RPID Hash invalid - Does not match policy 'example.com'

This error occurs while sending in the PublicKeyCredentialCreationOptions or PublicKeyCredentialRequestOptions to the FIDO Authenticator when there is a mismatch in the Relying Party Identifier (RPID) used by the client platform (Browser/Android/iOS) and the RPID configured in the StrongKey FIDO Server (SKFS) policy module. 

 

Fixing this problem

Resolve the problem by doing the following:

  1. Set RPID to a fixed value within the policy module of SKFS – the RPID was set during installation at Step 6 as shown in the installation steps here. The RPID may also be changed in the policy module that can be viewed here.
  2. Include this RPID value in PublicKeyCredentialCreationOptions and PublicKeyCredentialRequestOptions to the FIDO Authenticator– see below on how to do this.

 

Once this is completed and the Payara Application Server is restarted (see below on how to do this), a user can authenticate successfully with a registered FIDO credential using the configured RPID.

sudo service glassfishd restart

 

It is recommended to set the RPID for the Policy to the DNS Domain Name + Top Level Domain (TLD) like example.com instead of using a sub-domain like “auth.example.com”. This allows for the leverage of the JSON Web Token (JWT) or Security Assertion Markup Language (SAMLreturned by SKFS in a successful Authentication response to enable Single Sign-On (SSO) across all applications for an organization. For more information, see the section on Configuring SSO.

 

More Detailed Explanation

During the Registration/Authentication process, RPID is extracted from the authenticatorData and printed in the Payara logs as shown below:

[2023-01-01T09:22:43.765+0000] [Payara 5.2020.7] [FINE] [FIDO-MSG-2001] [SKFS] [tid: _ThreadID=164 _ThreadName=http-thread-pool::http-listener-2(4)] [timeMillis: 1672564963765] [levelValue: 500] [CLASSNAME: com.strongkey.skfs.utilities.SKFSLogger] [METHODNAME: log] [[FIDO-MSG-2001: FIDO 2 Debug Message : rpidHash : Vu1EVIMFv79c6oNEBO0MXIneBMNFgIoEoowe65YhNwY=]]

 

This rpidHash is compared against the Hash of RPID which is specified in the Policy and also printed in the logs as shown below:

[2023-01-01T09:22:43.769+0000] [Payara 5.2020.7] [INFO] [] [] [tid: _ThreadID=164 _ThreadName=http-thread-pool::http-listener-2(4)] [timeMillis: 1672564963769] [levelValue: 800] [[
rpidhashfrompolicy = MKVF6XACbKWbTQ7Z8cGFxXfBAHSJExaxmqt+kAQEkF0=]]

 

When the two RPID Hash do not match, SKFS throws the error “RPID Hash invalid - Does not match policy 'example.com'”. This can be verified by running the commands below. Calculate the hash of the RPID for testing purposes by running the following command on Linux:

echo -n 'example.com' | sha256sum | xxd -r -p | /usr/bin/base64

Note: Replace <example.com> with the RPID.

The response rpidHash doesn't match the policy rpidHash in the logs.

 

To fix this, set the correct RPID in PublicKeyCredentialCreationOptions during Registration on the Browser or Application. Here's a JavaScript example for the Browser:

const publicKeyCredentialCreationOptions = {
    challenge: Uint8Array.from(
        challengeStringFromServer, c => c.charCodeAt(0)),
    rp: {
        name: "StrongKey demo application",
        id: "strongkey.com",
    },
    user: {
        id: Uint8Array.from(
            "johndoe", c => c.charCodeAt(0)),
        name: "2ipST--mR0l_XeKR1l-sLYR4CgjdvdhrstXaypbnawk",
        displayName: "johndoe",
    },
    pubKeyCredParams: [{alg: -7, type: "public-key"}],
    attestation: "direct"
};

const credential = await navigator.credentials.create({
    publicKey: publicKeyCredentialCreationOptions
});

 

Below is an example of setting the RPID in PublicKeyCredentialRequestOptions during Authentication:

const publicKeyCredentialRequestOptions = {
    challenge: Uint8Array.from(
        challengeStringFromServer, c => c.charCodeAt(0)),
    rpId: "strongkey.com",
    allowCredentials: [{
        id: Uint8Array.from(
            credentialId, c => c.charCodeAt(0)),
        type: 'public-key',
        alg: -7,
    }],
    timeout: 60000,
}

const assertion = await navigator.credentials.get({
    publicKey: publicKeyCredentialRequestOptions
});

 

If the RPID is not provided, it will be automatically configured to the Origin, as outlined in the WebAuthn Specification for Registration in PublicKeyCredentialCreationOptions, found here, and for Authentication in PublicKeyCredentialRequestOptions,found here.