Yo use FIDO2 keys in web browsers, we have to use the FIDO2 Web Authentication (WebAuthn) API. WebAuthn is a set of standards and APIs that allows the browser to communicate with the operating system and deal with using cryptographic keys. WebAuthn falls under FIDO2 standards, but it was developed by the W3C.

We use a client-side JavaScript library called "webauth-json" that serves as a convenience wrapper for the WebAuthn API by encoding binary data using base64url. 

https://github.com/github/webauthn-json

This article demonstrates how to use the webauth-json JavaScript library and DualShield API to register a FIDO2 key for a user in a web browser. 

Import WebAuth-Jason

To use the webauth-jason, you need to install it first

npm install --save @github/webauthn-json

Install WebAuth-Jason

Then, you need to import it

import { create, CredentialCreationOptionsJSON, CredentialRequestOptionsJSON, get, PublicKeyCredentialWithAssertionJSON } from '@github/webauthn-json';

Create Objects

We need to create 3 objects, fidoObj, CredentialCreationOptionsJSON, and CredentialRequestOptionsJSON

fidoObj = {
    manufacturerCode: "DN",
    productCode: "FIDO2",
    method: "FIDO2"
  };

  credentialCreateOptions: CredentialCreationOptionsJSON = {
    publicKey: {
      rp: {
        name: ""
      },
      user: {
        name: "",
        displayName: "",
        id: ""
      },
      challenge: "",
      pubKeyCredParams: [],
      timeout: 0,
      excludeCredentials: [],
      authenticatorSelection: {userVerification: "discouraged"},
      attestation: "none",
    }
  };

  credentialRequestOptions: CredentialRequestOptionsJSON = {
    publicKey: {
      challenge: "",
      extensions:{
        appid:""
      },

    allowCredentials: [],
    userVerification: "discouraged"
    }
  };

Register a FIDO2 Key for a user

To register a FIDO2 key for a user, we call 2 DualShield APIs


Method: /token/preRegister


Example:

Request
{
    "product":{
        "productCode":"FIDO2",
        "method":"FIDO2",
        "manufacturerCode":"DN"
    },
    "params":{
        "serverAddress":"https://dualshield.deepnetsecurity.com:8074"
    },
    "user":{"loginName":"management\\xxx"}
}
Response
{
    "error": 0,
    "message": "Succeeded",
    "result": {
        "registerRequestData": "{\"rp\":{\"name\":\"deepnetsecurity.com\",\"id\":\"deepnetsecurity.com\"},\"user\":	
 		{\"name\":\"xxx\",\"displayName\":\"xxx\",\"id\":\"xxx\"},\"challenge\":\"4xXusQat1UEP4VmKiAVU2dPHopyzHOgb0OhjiLympTE\",\"pubKeyCredParams\":[{\"alg\":-7,\"type\":\"public-key\"},{\"alg\":-8,\"type\":\"public-key\"},
		{\"alg\":-257,\"type\":\"public-key\"}],\"excludeCredentials\":[],\"authenticatorSelection\":{\"userVerification\":\"preferred\"},\"attestation\":\"direct\",\"extensions\":
		{\"appidExclude\":\"https://dualshield.deepnetsecurity.com:8074\",\"credProps\":true}}",
        "registerRequestId": "6d462c7143e9f3ee79936ff4e9e947b9c7b978071bc56afdfc32a396223df2be"
    }
}

Method: /token/register


Example:

Request
{
    "product":{"productCode":"FIDO2"},
    "application":{"name":"Computer Logon"},
    "params":{"serverAddress":"https://dualshield.deepnetsecurity.com:8074"},
    "user":{"loginName":"xxx"},
    "token":{
         "pin":"xxx",
         "publicKeyCredentialJson":"{\"clientExtensionResults\":\"xxx\"}"
         "registerRequestId":"xxx"
    }
}
Response
{
    "error": 0,
    "result": {
        "serial": "xxx",
        "id": "xxx",
        "status": "ACTIVE",
        "needActivation": false,
        "tokenAssignmentId": "xxx"
    },
    "message": "Succeeded"
}

Pre-Register FIDO2 Token

First, we can the DualShield API token/preRegister to pre-register a FIDO2 token

Method: /token/preRegister


Example:

Request
{
    "product":{
        "productCode":"FIDO2",
        "method":"FIDO2",
        "manufacturerCode":"DN"
    },
    "params":{
        "serverAddress":"https://dualshield.deepnetsecurity.com:8074"
    },
    "user":{"loginName":"management\\xxx"}
}
Response
{
    "error": 0,
    "message": "Succeeded",
    "result": {
        "registerRequestData": "{\"rp\":{\"name\":\"deepnetsecurity.com\",\"id\":\"deepnetsecurity.com\"},\"user\":	
 		{\"name\":\"xxx\",\"displayName\":\"xxx\",\"id\":\"xxx\"},\"challenge\":\"4xXusQat1UEP4VmKiAVU2dPHopyzHOgb0OhjiLympTE\",\"pubKeyCredParams\":[{\"alg\":-7,\"type\":\"public-key\"},{\"alg\":-8,\"type\":\"public-key\"},
		{\"alg\":-257,\"type\":\"public-key\"}],\"excludeCredentials\":[],\"authenticatorSelection\":{\"userVerification\":\"preferred\"},\"attestation\":\"direct\",\"extensions\":
		{\"appidExclude\":\"https://dualshield.deepnetsecurity.com:8074\",\"credProps\":true}}",
        "registerRequestId": "6d462c7143e9f3ee79936ff4e9e947b9c7b978071bc56afdfc32a396223df2be"
    }
}

let json = {
    product: this.fidoObj,
    user: { loginName: this.loginName}, \\ Pass the user name to which the Fido2 key needs to be registered
};

The response from the preRegister API call is then passed to the CredentialCreationOptionsJSON object

\\ response is stored in data
this.registerRequestId = data.result.registerRequestId;
let registerObj = JSON.parse(data.result.registerRequestData);
if(registerObj){
            this.credentialCreateOptions.publicKey.rp.id = registerObj.rp.id;
            this.credentialCreateOptions.publicKey.rp.name = registerObj.rp.name;
            this.credentialCreateOptions.publicKey.user.displayName = registerObj.user.displayName;
            this.credentialCreateOptions.publicKey.user.id = registerObj.user.id;
            this.credentialCreateOptions.publicKey.user.name = registerObj.user.name;
            this.credentialCreateOptions.publicKey.timeout = 180000; //Set to 3 minutes
            this.credentialCreateOptions.publicKey.challenge = registerObj.challenge;
            this.credentialCreateOptions.publicKey.pubKeyCredParams = registerObj.pubKeyCredParams;
            this.credentialCreateOptions.publicKey.attestation = registerObj.attestation;
            this.credentialCreateOptions.publicKey.excludeCredentials = registerObj.excludeCredentials;
            this.credentialCreateOptions.publicKey.authenticatorSelection.userVerification= registerObj.authenticatorSelection.userVerification;   
          }

Now, pass the CredentialCreationOptionsJSON object to the create API in the WebAuthn-Jason library

create(this.credentialCreateOptions).then((response: any) => {
          let token: {publicKeyCredentialJson: string, pin?: string, registerRequestId: string} = {
            publicKeyCredentialJson: JSON.stringify(response),
            registerRequestId: this.registerRequestId,
          };

Register FIDO2 Token to a user

Finally, we call the DualShield API token/register to register the FIDO2 token

Method: /token/register


Example:

Request
{
    "product":{"productCode":"FIDO2"},
    "application":{"name":"Computer Logon"},
    "params":{"serverAddress":"https://dualshield.deepnetsecurity.com:8074"},
    "user":{"loginName":"xxx"},
    "token":{
         "pin":"xxx",
         "publicKeyCredentialJson":"{\"clientExtensionResults\":\"xxx\"}"
         "registerRequestId":"xxx"
    }
}
Response
{
    "error": 0,
    "result": {
        "serial": "xxx",
        "id": "xxx",
        "status": "ACTIVE",
        "needActivation": false,
        "tokenAssignmentId": "xxx"
    },
    "message": "Succeeded"
}

let json = {
      product:{productCode: this.fidoObj.productCode},
      application: {name: ""},
      user: { loginName: this.loginName },
      token: token
      };



  • No labels