davidearl / webauthn Goto Github PK
View Code? Open in Web Editor NEWAn implementation of webauthn in PHP on the server side (e.g Yubico 2 and Google Titan keys)
Home Page: https://webauthn.davidearl.uk
License: MIT License
An implementation of webauthn in PHP on the server side (e.g Yubico 2 and Google Titan keys)
Home Page: https://webauthn.davidearl.uk
License: MIT License
Hello.
Fingerprint authentication is no longer working in the Safari browser on my iPhone.
What is the cause and will you fix the software in the future?
Confudes regaridn importing the webauthn.php directory to the project.. does that get imported by composer..... i didnt see any require in the index.php file
Hi there,
thanks for your (really awesome) Work.
I was forced now to remove this Library out of our Composer Project, as we cannot support PHPSecLib2 anymore.
Would it be possible for you to switch to V3 or maintain both Versions? (its basically only replace "RSA" with the "PublicKeyLoader::load" Concept from V3, everything else could stay.
Thanks a lot!
Christoph
Attempting to create a key only allows for certification through security key, but not via other ways (e.g. Pin Auth on Win 10 or fingerprint on Android) - both platforms only request a security key.
Might be caused by not allowing self-certification or whatever that's called? Sorry, not very experienced with the WebAuthn inner workings ... works on both platforms with the webauthn.io test page, allowing either security dongles or other methods ...
User Registration in Safari returns this error. Something goes wrong when checking the rpId hash?
Both Firefox and Chrome work fine. Also after registering in another browser, User Login does work in Safari.
Hello, I am trying to use the library for an implementation. I am having a problem after registering the device (it works perfectly) and then when trying to authenticate, the Windows modal appears to enter a USB access key but later when canceling (to enter with the fingerprint stored on my device) the operation aborts .
This happens both in the demo and in my server integration.
I can't find where the problem is, the code was not changed at all.
Because it double encodes the dot on read but not on write.
For local machine when I am trying to run this code its showing me appid issue for class contractor method, here I can see need to pass host name as argument and I am passing localhost but its not working and showing error.
public function __construct($appid)
{
if (! is_string($appid)) {
$this->oops('appid must be a string');
}
$this->appid = $appid;
if (strpos($this->appid, 'https://') === 0) {
$this->appid = substr($this->appid, 8); /* drop the https:// */
}
}
Requires ->get_byte_string() on objects currently passed to bin2hex
Hello
The library works without problems in Mac OS X with Firefox, Chrome, Opera and Safari. (all last versions)
On Windows 10 version 1903, it works well under Chrome, but against Firefox and Edge, I have this error message when I want to register a key (yubikey and keydo)
"cannot decode FIDO format responses, sorry"
on the other hand if I save the keys with Chrome, I can authenticate without problem with Firefox and Edge.
Yet it worked well with Firefox before the 1903 update! and Chrome too ... Edge never worked as a key record.
Thank you for your work
(i use the "master" branch with the last commit)
Hello,
I am testing Yubikey securitykey with Firefox 90.0.2 version on Windows 10. In the navigator.credentials.create() API, I am providing the attestation value as "none" . But the response from this API returns the fmt attribute of the attestationobject as "fmt": "packet" which was supposed to be "none". Could anyone let me know if am missing any information.
The same use case when tested on MAC + Firefox + Security key return the attestationobject as "fmt": "none" which is expected.
Thanks in advance!
Shiny
I'm trying to implement excludeCredentials in prepare_challenge_for_registration by supplying a list of PublicKeyCredentialDescriptor's I have registered just like the code in prepare_for_login, using the same key objects I pull from DB:
$denies = array();
if (! empty($exclude)) {
$deny = (object)array();
$deny->type = 'public-key';
$deny->transports = array('usb','nfc','ble');
foreach(json_decode($exclude) as $key) {
$deny->id = $key->id;
$denies[] = clone $deny;
}
}
$result->excludeCredentials = $denies;
but my client (Google Chrome) keeps crashing on creating the CredentialsContainer:
TypeError: Failed to execute 'create' on 'CredentialsContainer': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'
If I log the respective challenges, the allowCredentials and excludeCredentials object are frighteningly similar, but registration keeps failing and validation succeeds?
[excludeCredentials] => Array
(
[0] => stdClass Object
(
[type] => public-key
[transports] => Array
(
[0] => usb
[1] => nfc
[2] => ble
)
[id] => Array
(
[0] => 188
[1] => 242
[allowCredentials] => Array
(
[0] => stdClass Object
(
[type] => public-key
[transports] => Array
(
[0] => usb
[1] => nfc
[2] => ble
)
[id] => Array
(
[0] => 188
[1] => 242
Does anybody have any clue what might be going wrong here?
if you clear your cookies/$_SESSION after registration you get error "login failed: Bad Request: username not set" while attempting to login.
Hello and thanks for such a useful piece of code. Thanks to the samples I managed to implement WebAuthn in no time.
However, now I need to take it further and apply some customization. I find that all the various json_encode
's and unnecessary stuff like this are impeding progress. Would you move the serialization responsibility elsewhere (or remove it altogether, since each developer will likely persist keys his/her own way) and allow options to be fed into prepareChallengeForRegistration and prepareForLogin?
Also, do you accept pull requests?
I've been dying to try this, but I've been plagued with an issue for over 5 hours now. After five hours of printing, debugging, switching servers, I'm here surrendering.
Installed your script + dependencies, and I am greeted with Couldn't initiate registration.
When I first installed, when I clicked registration, it actually printed my entire homepage in code. I went through your github issue list, and you mentioned something about the links and it looking in a specific folder.
So I moved things around, and finally got the error to disappear, and now the Couldn't initiate registration is my next issue.
https://i.imgur.com/FInE0AN.png
If I go into chrome developer tools; I notice it lists index.php with a 500 error for POST. I tried self hosting the .js on the same server running the script, thinking maybe something was blocking the external hosted file, and that did nothing.
I am indeed using Cloudflare, but I thought at one point maybe Cloudflare is blocking something with the request; so I actually disabled cloudflare and that did nothing.
https://i.imgur.com/puCffZo.png
I then finally got irritated enough to do a quick install of XAMPP via localhost and install the script.
It appeared to work fine and allowed me to create a user, I just receive Invalid Domain.
https://i.imgur.com/Zi3CSJl.png
Which is a heck of a lot more program than my official website
Any help would be amazing. I'm at a loss for words. I figured by disabling Cloudflare; if it was indeed cloudflare blocking the request for some reason; disabling it would address it, but nothing has changed.
Edit: Completely disabled Cloudflare; turned off HTTPS rewrite; nothing to do with that service whatsoever. Same error.
Regards
I created a blank project with composer init
. I then tried to run composer require davidearl/webauthn
but it failed with the following output:-
[InvalidArgumentException]
Could not find a version of package davidearl/webauthn matching your minimum-stability (stable). Require it with an explicit version constraint allowing its desired stability.
How can I add this to my project? When I was prompted for a value for "Minimum Stability" I left it blank, so I presume it uses stable as a default.
registration failed: Bad Request: cannot decode key response (8)
it's possible to use "navigator.credentials" with Android Webview ?
navigator.credentials.get()
and others are present in webview, but nothing happens!
you have to allow something on the "server" side or in the application that uses the "Webview"?
Thank you
Is there any way to store multiple keys for one user?
In webauthnregister.js, following check is performed:
if ('https://'+key.publicKey.rp.name != cd.origin) { return cb(false, 'key returned something unexpected (2)'); }
I know this project assumes that the rp.name and rp.id are identical and refer to the FQDN of where the project is hosted. However, the webauthn spec states the following:
The RP ID must be equal to the origin's effective domain, or a registrable domain suffix of the origin's effective domain.
My use case requires the registration step and the authentication step to be on different subdomains of the same main domain, which makes me pass the main domain as the rp.id, which in turn makes the above check fail.
As browsers already check the rp.id requirement, I feel the above check is unnecessary and could be removed. Another option would be to perform a more advanced check conform to the spec.
Hello,
i am testing your example website (https://webauthn.savesnine.info/) and i got this error.
TypeError: Element of 'transports' member of PublicKeyCredentialDescriptor 'internal' is not a valid value for enumeration AuthenticatorTransport.
I am using Linux and FF 60.9.0esr
In webauthn.php, there's following code:
$publickey->rpid = str_replace('https://', '', $this->appid);
This rpid key is directly used for the challenge in the authentication request. However, at least a few browsers treat the json key case-sensitively and the authenticator will not be able to find any of the IDs that were provided. This should fix the issue:
$publickey->rpId = str_replace('https://', '', $this->appid);
After updating to iOS 17.4.1, we've noticed a change in behavior with this library. Instead of the usual passkey selection menu, a QR code is now displayed as shown below:
To temporarily address this, removing the 'internal' reference from WebAuthn.php resolves the issue.
$allow->transports = array('usb','nfc','ble');
(was $allow->transports = array('usb','nfc','ble','internal');
However, please note that this fix may impact the platform authentication option on desktop browsers.
For months now I have been using Passkeys stored in 1Password and all of a sudden they are not working. Without changing any code I could create a new Passkey in iCloud Keychain and use this instead, it works. Something obviously changed in 1Password. There was a recent update. I did try creating a new Passkey in 1Password but it still wouldn't authenticate.
Hello,
Please let me know what needs to be change to enable webauthn.php to accept bio-metric based authentication. Current script does not have that option available.
Regards,
Gaurav Maniar
Hey David,
There's a few closed issues around the fingerprint feature not being available. I've read and followed your instructions on how to resolve the issue, but I still seem to end up with errors.
Now that this is a standard feature that you can test with, have you got plans to implement it? - I for one would be very grateful for a working example.
The setting authenticatorSelection->authenticatorAttachment = 'cross-platform' in prepareChallengeForRegistration associates the identity with the authenticator device (eg Yubikey) rather than the platform (Windows Hello). The former allows the same device to be used on different computers, but only that device can be used., The latter allows any authentication method available (e.g. Windows PIN instead of fingerprint reader) to be used, whichever device was used to register, but only on that one computer.
Ultimately this setting needs to be selected by and explained to the end user, which is problematic. Why can't Windows Hello just try both?
Hello
you have "$username" and "$userid" for parameters with this function :
$webauthn->prepare_challenge_for_registration($username, $userid)
this is just for your database json system ?
it's not use in u2f authentication if i use mysql or others ?
Hello, when I ran the code on my localhost, I got the error mentioned in the title, generated by clicking the submit button on user registration. However, after I googled it, nothing that I found seemed to match my problem. (e.g. I have no missing parantheses or anything like this). Do you know what this error might be caused by?
Thank you in advance.
Hello
I'm trying to run your example but I'm getting this error message
TypeError: navigator.credentials is undefined
however i am using a valid ssl certificate and your demo works fine on my browsers
thanks for your help
Hi there,
thats for that really usefull and comprehensive Work, I appreciate it a lot :)
Everything works fine and I was able to implement it as we needed it.
One last Thing though - is it possible to extract any Kind of Information of "what kind of Device" this is? Maybe the Manufacturer, Model, or at least Type (USB, Fingerprint etc?).
Is this somewhere hidden in the returned encrypted Strings?
Thanks!
Christoph
HI Guys.
looking at the specs i can add icon at the rp object and have an icon displayed at the ui.
I tried doing that but there is now icon showing...
any one know if thats a bug or am i doing something wrong.
Hello,
When I try to log the aaguid ( in the register function, $ao->attData->aaguid ) I gives me a strange text like "^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@"
What could have caused this? Anyone seen this before?
Regards
Emin
Hello,
Thanks for this great software!
I'm current reducing the html & js part to a minimum.
My php-skript creates a html output with the challenge allready in a variable.
The js-part only creates the response and calls itself with the response as a get-parameter.
This works fines.
https://rdpdev.secureaccess.pro/testwa/example/4login.php
But I realized that there is no timeout.
I can refresh the page with the get-parameter and after 5 minutes $webauthn->authenticate return "OK".
I see the timeout fields during creation, but they are not checked.
This does not happen in your JS-version and POST.
But this error should be there even if it is harder to show.
Stefan
Are there any plans to support discoverable credentials? It may not be to difficult because it mainly needs to set $result->authenticatorSelection->requireResidentKey
to true during registration and not setting $publickey->allowCredentials
during login.
As title - register allows me to use the finger print sensor, but on log in, Chrome's UI requires me to use a USB security key. Chrome 77, MacOS 10.14.6.
Is there a way to check in the register() function whether this yubikey or device has already been registered for the user?
At the moment I can register several devices for one user, but unfortunately it does not recognize if a device (yubikey) has already been registered for the user.
At the moment I can register the identical yubikey infinite times for the same user.
[email protected] nyc /home/cdac/Tejas/caliper
nyc mocha --recursive -t 10000
/home/cdac/Tejas/caliper/src/comm/util.js:131
static log(...msg) {
^^^
SyntaxError: Unexpected token ...
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:374:25)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Module.require (module.js:354:17)
at require (internal/module.js:12:17)
at /home/cdac/Tejas/caliper/src/comm/rate-control/fixedRate.js:18:13
at Object. (/home/cdac/Tejas/caliper/src/comm/rate-control/fixedRate.js:173:4)
at Module._compile (module.js:410:26)
at Module.module._compile (/home/cdac/Tejas/caliper/node_modules/rewire/lib/moduleEnv.js:124:18)
at Object.Module._extensions..js (module.js:417:10)
at Object.jsExtension (/home/cdac/Tejas/caliper/node_modules/rewire/lib/moduleEnv.js:132:24)
at Module.load (module.js:344:32)
at Object.load (/home/cdac/Tejas/caliper/node_modules/rewire/lib/moduleEnv.js:55:18)
at internalRewire (/home/cdac/Tejas/caliper/node_modules/rewire/lib/rewire.js:49:15)
at rewire (/home/cdac/Tejas/caliper/node_modules/rewire/lib/index.js:11:12)
at Object. (/home/cdac/Tejas/caliper/test/comm/rate-control/fixedRate.js:18:19)
at Module._compile (module.js:410:26)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Module.require (module.js:354:17)
at require (internal/module.js:12:17)
at /usr/lib/nodejs/mocha/lib/mocha.js:172:27
at Array.forEach (native)
Hi, great work! Found a bug though: registering works, chrome prompts for 3 types of hard keys and fingerprint option. When try to login, the fingerprint option is missing... Tried to add internal to transport options but no effect. On webauthn.io it works very smooth because it saves the device type so you can immediatly use fingerprint for login instead of having to selecting it first. Maybe a good addition? Try webauthn.io on mobile to see what i mean ;)
I've noticed that the signed challenges can be reused. From your example there's nothing that validates the challenge that was sent to the browser, was the same challenge that was sent back. For example:
Challenge sent bytes: 1,2,3,4,5,6,etc
Challenge is signed and the originalChallenge is sent back to 1,2,3,4,5,6,etc
Another challenge is sent with bytes: 7,8,9,0,1,2,3,etc
Previous challenge is sent back with 1,2,3,4,5,6,etc. and accepted
I think the challenge that is sent to the browser needs to be stored in the SESSION and compared with when receving the signed challenge.
I solved this in my code:
$login = json_decode($_POST["login"]);
$original = json_decode($_SESSION["original"]);
if($original->challenge !== $login->originalChallenge) {
return false;
}
if(!$webauthn->authenticate($_POST["login"], $userwebauthn)) {
return false;
}
$_SESSION["original"] = null;
However this should probably be one of the parameters to authenticate.
Hello,
Thanks for this very good job!
I'am trying to understand the code but when I try to implement it on my server I have the following message: Couldn't initiate registration: SyntaxError: Unexpected token < in JSON at position 1
The /.users is created with 777chmod. No json file is present in the /.users directory
URL: http://35.190.191.90/webauthn/example/index.php
Thanks for you time and your help...
Rémi
First thing: Huge thanks for creating this library and for all the hours and hours of work it must have taken. Wonderful stuff.
I have enabled it on my various personal websites and it works absolutely wonderfully with a Google Titan USB key.
However, I would also like to my Honor 9 Lite (Android 9) mobile phone to access these websites.
When I use Firefox or Chrome on my mobile, it only comes up with USB or NFC Security key options and does not offer the opportunity to use finger print etc.
It seems not an issue with the phone as I was able to register with passkeys.io using finger print absolutely fine.
However, on my website and yours (https://webauthn.davidearl.uk/) it fails to offer finger print.
Any ideas what I am doing wrong?
Many thanks once again, and any help that you can offer will be most gratefully received.
Hello
you use "random_bytes" function, this function is only in php 7+
we should either limit the "compose" with php 7+
OR use this library to make it compatible with php 5.6
https://github.com/paragonie/random_compat
OR use "openssl_random_pseudo_bytes" compatible with 5.6 and 7+
Thanks
I don't know if the question is about the library or I have to manage this at implementation level, but isn't clear for me how to manage multiple devices.
For example, if I have to store for the same user the data about a mobile (with fingerprint) AND my macbook (with fingerprint) for the same user, how to manage it?
I read the protocol allows multiple authenticators, but in this library I cannot do it.
Thanks
Fingerprint verification is not offered, only bluetooth, NFC or USB key.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.