Click here to Skip to main content
15,886,857 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Everyone,

I have a web application that will require finger print validation. Is it possible for me to allow users of the application to browse the app on their respective mobile phone and use their smart phone finger print scanner to validate their finger prints which I will match with already captured finger prints and notify them with successful or not message.

The idea is to avoid buying multiple scanner or have a PC attached to a scanner at a position since it is a C2B model.

I look forward to your wonderful responses.

What I have tried:

I have desktop working version of fingerprint capture and validation solution using SecuGen finger print scanner
Posted
Updated 15-Feb-22 21:55pm
v3

1 solution

Yes, it is possible with your smart phone and your laptop(if fitted with a biometric scanner)

Always keep in mind that Google is your friend, I have found the following article from Vasyl Boroviak who explains the workings behind the scanner with solid code. For future users I will post his code here, I do however suggest to read the entire article to understand the why, who, when and how of using the biometric scanner.

HIS ARTICLE is an indepth description, trust this will work for you -

Here is a server-side pseudo code::
const deviceId = req.cookies["my-long-live-cookie"];
const device = await devices.findById(deviceId);
if (!device) return {};
device.challenge = require("crypto").randomBytes(16).toString("hex")
await device.save();
return { challenge: device.challenge };


The devices table minimum schema looks like this:
_id: String, // long lived cookie
challenge: String, // server side random generated string
counter: Number, // protects from the so called replay attacks
publicKey: String, // public key created by the fingerprint scanner
attestationObject: String, // low level device data (BASE64 binary)
clientDataJSON: String, // BASE64 encoded JSON info of the website
userAgent: String, // last seen user-agent HTTP header
user: ObjectId, // the link back to the user, aka the foreign key


create-public-key
This is the point when your browser invokes the WebAuthn API to scan user’s finger for the first time. (See explanation below.)
import { decode: base64urlDecode } from "base64url";
const attestation = await navigator.credentials.create({
    publicKey: {
        authenticatorSelection: {
            authenticatorAttachment: "platform",
            userVerification: "required"
        },
        challenge: base64urlDecode(challenge),
        rp: { id: document.domain, name: "My Acme Inc" },
        user: {
            id: base64urlDecode(user.id),
            name: user.email,
            displayName: user.fullName
        },
        pubKeyCredParams: [
            { type: "public-key", alg: -7 },
            { type: "public-key", alg: -257 }
        ]
    }
});
navigator.credentials.preventSilentAccess();
import { encode: base64urlEncode } from "base64url";
function publicKeyCredentialToJSON(pubKeyCred) {
    if (pubKeyCred instanceof ArrayBuffer) {
        return base64urlEncode(pubKeyCred);
    } else if (pubKeyCred instanceof Array) {
        return pubKeyCred.map(publicKeyCredentialToJSON);
    } else if (pubKeyCred instanceof Object) {
        const obj = {};
        for (let key in pubKeyCred) {
            obj[key] = publicKeyCredentialToJSON(pubKeyCred[key]);
        }
        return obj;
    } else return pubKeyCred;
}
const webAuthnAttestation = publicKeyCredentialToJSON(attestation);
fetch("example.com/save-public-key", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: webAuthnAttestation
});


The returned webAuthnAttestation looks like this:
{
    id: "a_very_very_long_string",
    type: "public-key",
    response: {
        attestationObject: "even_longer_string",
        clientDataJSON: "another_very_long_string"
    }
}


Decoding the clientDataJSON string.
const base64url = require("base64url");
clientDataJSON = JSON.parse(base64url.decode(clientDataJSON));

//The clientDataJSON checks: challenge must be the same as the one we sent to the //browser. origin must be our website hostname. type must be "webauthn.create".

assert(clientDataJSON.challenge === device.challenge)
assert(clientDataJSON.origin === "example.com");
assert(clientDataJSON.type === "webauthn.create");

//The attestationObject is a bit more complex though.
//Firstly, you need to parse it.

const base64url = require("base64url");
const cbor = require("cbor");
function parseAttestationObject(attestationObject) {
    const buffer = base64url.toBuffer(attestationObject);
    return cbor.decodeAllSync(buffer)[0];
}
const makeCredsReponse = parseAttestationObject(attestationObject);


Pseudo code:
device.counter = 0; // we must reset the counter
device.publicKey = publicKey;
device.type = type;
device.attestationObject = attestationObject;
device.clientDataJSON = clientDataJSON;
device.userAgent = req.headers["user-agent"];
await device.save();


This is for a re-login but can be adjusted to suit your needs i.e. comparison to your already saved prints...
 
Share this answer
 
Comments
Ibpet11 16-Feb-22 8:01am    
Thank you Mr Andre,

can I use the fingerprint scanner on mobile phones or laptop as a biometric device via my web application?
Andre Oosthuizen 16-Feb-22 12:51pm    
Only a pleasure, yes you can, see the link provided.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900