Yubico / python-fido2

Provides library functionality for FIDO 2.0, including communication with a device over USB.
BSD 2-Clause "Simplified" License
432 stars 109 forks source link

Consistently getting ValueError('Wrong challenge in response.') #48

Closed robwise1 closed 5 years ago

robwise1 commented 5 years ago

I apologize as this is likely an issue in my code, and not the repo- but I have tried this for days to no avail, and the lack of documentation is exacerbating my confusion.

I am running a local https server and testing FIDO2 keys. I generate a key like this:

registration_data, state = server.register_begin({
            u'id': '1',
            u'name': 'my user',
            u'displayName': 'my user',
             }, credentials)
request.session['fido2_state'] = state
# generate pubkey to pass to front end credential 
publicKey = {
       'challenge': websafe_encode(registration_data['publicKey']['challenge']),
       'rp': {
           'name':'Example Inc.',
           'id': 'localhost',
        },
        'user': {
             'id': 1,
             'name': 'alice@example.com',
              'displayName': 'Alice von Wunderland'
         },
        'pubKeyCredParams': [
                { 'type': 'public-key', 'alg': -7  },
                { 'type': 'public-key', 'alg': -257 }
         ]
}
return render(request, self.template_name, {'registration_data':  publicKey})

And in the front end:

//Get response from server and convert values to array buffer 
publicKey = {{ registration_data | safe }}
challenge = publicKey['challenge']
user_id = publicKey['user']['id']
publicKey['challenge'] = str2ab(challenge)
publicKey['user']['id'] = str2ab(user_id)
navigator.credentials.create({ 'publicKey': publicKey }) .then(function(attestation) {
                return fetch('/fido/', {
                    method: 'POST',
                    credentials: 'same-origin',
                    headers: {'Content-Type': 'application/cbor'},
                    body: CBOR.encode({
                      "attestationObject": new Uint8Array(attestation.response.attestationObject),
                      "clientDataJSON": new Uint8Array(attestation.response.clientDataJSON),
                    });
             });
        });

Once it's posted to server, I get the data from the request and try to verify

       # verify response from server
        data = cbor.loads(request.body)[0]
        client_data = ClientData(data['clientDataJSON'])
        att_obj = AttestationObject(data['attestationObject'])
        state = request.session['fido2_state']
        auth_data = server.register_complete(
            state,
            client_data,
            att_obj
        )

This consistently returns

  File "/usr/local/lib/python2.7/dist-packages/fido2/server.py", line 180, in register_complete
    raise ValueError('Wrong challenge in response.')

I am completely lost. I have tried the few examples I have found online. However I truly have no idea how to proceed. My guess is my encoding of the challenge in the original registration challenge generation is incorrect, but I'm not sure what to do. I have tried encoding this in a variety of ways, completely unsuccessfully.

I would appreciate any hints here. If this is too far out of the scope for these issues, I apologize and will close it out.

mkalioby commented 5 years ago

Hi,

You can try django-mfa2 (https://github.com/mkalioby/django-mfa2) which integrates FIDO2 Keys in Django

robwise1 commented 5 years ago

Hello! I've actually been using your django-mfa2 as a primary example and it has been pretty helpful and I appreciate the work. However the current build of django-mfa2 doesn't work with django1.11. I will raise an issue there if you would like- I may be able to open a PR with fixes as well.

That said, after taking an even closer look at how you are handling encoding of the CBOR data from the django server to the front end- I was able to solve my problem.

I greatly appreciate your help- closing this out.

mkalioby commented 5 years ago

we can work on it or you can open a PR (which will be much appreciated) as well