lbuchs / WebAuthn

A simple PHP WebAuthn (FIDO2/Passkey) server library
https://webauthn.lubu.ch
MIT License
419 stars 75 forks source link

How can I authenticate against registration data stored in a MySQL database? #79

Closed JRiggles closed 9 months ago

JRiggles commented 9 months ago

Using the example PHP as a template, I'm trying to move from $_SESSION-based storage to a MySQL database.

I've created DB entries for userId, credentialId, credentialPublicKey, and signatureCounter, but I can't figure out how to then use that information to validate my security key (a Yubikey, in my case) after creating the registration.

Here's an example of my working database entry creation code ($dbh here is my database connection):

function createRegistration($dbh, $data) {
    // get values from $data
    $userId = $data->userId;
    $credentialId = $data->credentialId;
    $credentialPublicKey = $data->credentialPublicKey;
    $signatureCounter = $data->signatureCounter;
    // construct and execute the database query
    $query = $dbh->prepare(
        "INSERT INTO 2FARegistrations
         VALUES(:userId, :credentialId, :credentialPublicKey, :signatureCounter)"
    );
    $query->bindParam(':userId', $userId);
    $query->bindParam(':credentialId', $credentialId);
    $query->bindParam(':credentialPublicKey', $credentialPublicKey);
    $query->bindParam(':signatureCounter', $signatureCounter);
    $query->execute();
}

And here is how I get the values for userId, credentialId, credentialPublicKey, and signatureCounter to pass into my createRegistration function (largely taken from the example code, as well as this issue):

$data = $WebAuthn->processCreate($clientDataJSON, $attestationObject, $challenge, $userVerification === 'required', true, false);
$data->credentialId = base64_encode($data->credentialId);
$data->signatureCounter = ($data->signatureCounter === null ? 0 : $data->signatureCounter);
$data->userId = $userId;
$data->userName = $userName;
$data->userDisplayName = $userDisplayName;

createRegistration($dbh, $data);

This does create the appropriate database entry, but I cannot figure out how to use this information to then authenticate the "registered" user with their security key. Any help is appreciated - let me know if there's anything I can clarify.

JRiggles commented 9 months ago

As it turns out, the issue was with my database's credentialId column. I had set it to a width of 64, which was truncating the base-64 encoded value and breaking things. Setting the width to 1024 (as indicated in Database Entity Relationship here) fixed the issue!