print("New credential created!") print("CLIENT DATA:", client_data) print("ATTESTATION OBJECT:", attestation_object) print() print("CREDENTIAL DATA:", auth_data.credential_data) # Prepare parameters for getAssertion request_options, state = server.authenticate_begin(user_verification=uv) # Authenticate the credential if use_prompt: print("\nTouch your authenticator device now...\n") assertions, client_data = client.get_assertion(request_options["publicKey"], pin=pin) assertion = assertions[ 0] # Only one cred in allowCredentials, only one response. # Complete authenticator server.authenticate_complete( state, credentials, assertion.credential["id"], client_data, assertion.auth_data, assertion.signature, ) print("Credential authenticated!")
def sign_request(public_key, authn_select): """Signs a WebAuthn challenge and returns the data. :param public_key dict containing `rpId` the relying party and `challenge` the received challenge :param authn_select string, that contains the allowed public key of the user :return dict containing clientDataJSON, authenticatorData, signature, credentialId and userHandle if available. """ use_prompt = False pin = None uv = "discouraged" if WindowsClient.is_available( ) and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") use_prompt = True else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e: print("NFC channel search error:", e) if not dev: print("No FIDO device found") sys.exit(1) client = Fido2Client(dev, "http://localhost:8080", verify=lambda x, y: True) # Prefer UV if supported if client.info.options.get("uv"): uv = "preferred" print("Authenticator supports User Verification") elif client.info.options.get("clientPin"): # Prompt for PIN if needed pin = getpass("Please enter PIN: ") else: print("PIN not set, won't use") # the base64 library does not work when padding is missing, so append some allowed_key = base64.urlsafe_b64decode(authn_select + '===') pubKey = PublicKeyCredentialRequestOptions( public_key['challenge'], rp_id=public_key['rpId'], allow_credentials=[ PublicKeyCredentialDescriptor(PublicKeyCredentialType.PUBLIC_KEY, allowed_key) ]) # Authenticate the credential if use_prompt: print("\nTouch your authenticator device now...\n") # Only one cred in allowCredentials, only one response. result = client.get_assertion(pubKey, pin=pin).get_response(0) data = { "clientDataJSON": b64encode(result.client_data), "authenticatorData": b64encode(result.authenticator_data), "signature": b64encode(result.signature), "credentialId": b64encode(result.credential_id), } if result.user_handle: data['userHandle'] = b64encode(result.user_handle) return data
print("New credential created!") print("CLIENT DATA:", result.client_data) print("ATTESTATION OBJECT:", result.attestation_object) print() print("CREDENTIAL DATA:", auth_data.credential_data) # Prepare parameters for getAssertion request_options, state = server.authenticate_begin(user_verification=uv) # Authenticate the credential if use_prompt: print("\nTouch your authenticator device now...\n") selection = client.get_assertion(request_options["publicKey"], pin=pin) result = selection.get_response( 0) # There may be multiple responses, get the first. print("USER ID:", result.user_handle) # Complete authenticator server.authenticate_complete( state, credentials, result.credential_id, result.client_data, result.authenticator_data, result.signature, )
print("CLIENT DATA:", result.client_data) print("ATTESTATION OBJECT:", result.attestation_object) print() print("CREDENTIAL DATA:", auth_data.credential_data) # Prepare parameters for getAssertion request_options, state = server.authenticate_begin(credentials, user_verification=uv) # Authenticate the credential if use_prompt: print("\nTouch your authenticator device now...\n") # Only one cred in allowCredentials, only one response. result = client.get_assertion(request_options["publicKey"], pin=pin).get_response(0) # Complete authenticator server.authenticate_complete( state, credentials, result.credential_id, result.client_data, result.authenticator_data, result.signature, ) print("Credential authenticated!") print("CLIENT DATA:", result.client_data) print()
) credentials = [auth_data.credential_data] print("New credential created!") print("CLIENT DATA:", result.client_data) print("ATTESTATION OBJECT:", result.attestation_object) print() print("CREDENTIAL DATA:", auth_data.credential_data) # Prepare parameters for getAssertion request_options, state = server.authenticate_begin(credentials, user_verification=uv) # Authenticate the credential result = client.get_assertion(request_options["publicKey"]) # Only one cred in allowCredentials, only one response. result = result.get_response(0) # Complete authenticator server.authenticate_complete( state, credentials, result.credential_id, result.client_data, result.authenticator_data, result.signature, ) print("Credential authenticated!")
print("New credential created!") print("CLIENT DATA:", result.client_data) print("ATTESTATION OBJECT:", result.attestation_object) print() print("CREDENTIAL DATA:", auth_data.credential_data) # Prepare parameters for getAssertion request_options, state = server.authenticate_begin(credentials, user_verification=uv) # Authenticate the credential try: result = client.get_assertion( request_options["publicKey"], on_keepalive=on_keepalive ) except PinRequiredError as e: if isinstance(e.cause, CtapError): print(e.cause) result = client.get_assertion( request_options["publicKey"], on_keepalive=on_keepalive, pin=getpass("Enter PIN: "), ) # Only one cred in allowCredentials, only one response. result = result.get_response(0) # Complete authenticator server.authenticate_complete(