def run(self): user = { 'id': b"user_id", 'name': "User", } challenge = generate_challenge() hmac_ext = HmacSecretExtension(self._client.ctap2) # make the credential try: attestation_object, client_data = self._client.make_credential( { "rp": RELYING_PARTY, "user": user, "challenge": challenge, "pubKeyCredParams": [{ "type": "public-key", "alg": -7 }], # ES256 algorithm "extensions": hmac_ext.create_dict(), }, event=self._state._stop_event, ) except: return credential = attestation_object.auth_data.credential_data dev_id = self._client.info.aaguid cred_id = credential.credential_id with self._state as state: challenge = generate_challenge() salt = CipherData.generate_salt() allow_list = [{"type": "public-key", "id": cred_id}] assertions, client_data = self._client.get_assertion( { "rpId": RELYING_PARTY["id"], "challenge": challenge, "allowCredentials": allow_list, "extensions": hmac_ext.get_dict(salt), }, ) if assertions: # make a key and encrypt it with the secret secret = hmac_ext.results_for(assertions[0].auth_data)[0] packed_id = CipherData.pack_id(dev_id, cred_id, salt) if self._key: key = self._key packed_key = CipherData.pack_key(secret, key) else: key, packed_key = CipherData.generate_key(secret, 32) with open(self._key_path, 'wb') as key_file: key_file.write(packed_key) with open(self._id_path, 'wb') as id_file: id_file.write(packed_id) state.data = {"key": key, "cred_id": cred_id}
def simple_secret( credential_id, secret_input, host="nitrokeys.dev", user_id="they", serial=None, prompt="Touch your authenticator to generate a response...", output=True, udp=False, ): user_id = user_id.encode() from pynitrokey.fido2 import find client = find(solo_serial=serial, udp=udp).client hmac_ext = HmacSecretExtension(client.ctap2) # rp = {"id": host, "name": "Example RP"} client.host = host client.origin = f"https://{client.host}" client.user_id = user_id # user = {"id": user_id, "name": "A. User"} credential_id = binascii.a2b_hex(credential_id) allow_list = [{"type": "public-key", "id": credential_id}] challenge = secrets.token_hex(32) h = hashlib.sha256() h.update(secret_input.encode()) salt = h.digest() if prompt: print(prompt) assertions, client_data = client.get_assertion({ "rpId": host, "challenge": challenge.encode("utf8"), "allowCredentials": allow_list, "extensions": hmac_ext.get_dict(salt), }) assertion = assertions[0] # Only one cred in allowList, only one response. response = hmac_ext.results_for(assertion.auth_data)[0] if output: print(response.hex()) return response
def simple_secret( credential_id, secret_input, host="solokeys.dev", user_id="they", serial=None, pin=None, prompt="Touch your authenticator to generate a response...", output=True, udp=False, ): user_id = user_id.encode() client = solo.client.find(solo_serial=serial, udp=udp).client hmac_ext = HmacSecretExtension(client.ctap2) # rp = {"id": host, "name": "Example RP"} client.host = host client.origin = f"https://{client.host}" client.user_id = user_id # user = {"id": user_id, "name": "A. User"} credential_id = binascii.a2b_hex(credential_id) allow_list = [{"type": "public-key", "id": credential_id}] challenge = secrets.token_bytes(32) h = hashlib.sha256() h.update(secret_input.encode()) salt = h.digest() if prompt: print(prompt) options = PublicKeyCredentialRequestOptions( challenge, 30000, host, allow_list, extensions=hmac_ext.get_dict(salt) ) assertions, client_data = client.get_assertion(options, pin=pin) assertion = assertions[0] # Only one cred in allowList, only one response. response = hmac_ext.results_for(assertion.auth_data)[0] if output: print(response.hex()) return response
def run(self): challenge = generate_challenge() hmac_ext = HmacSecretExtension(self._client.ctap2) allow_list = [{"type": "public-key", "id": self._cred_id}] try: assertions, client_data = self._client.get_assertion( { "rpId": RELYING_PARTY["id"], "challenge": challenge, "allowCredentials": allow_list, "extensions": hmac_ext.get_dict(self._salt), }, event=self._state._stop_event, ) except: return with self._state as state: secret = hmac_ext.results_for(assertions[0].auth_data)[0] packed_key = open(self._key_path, 'rb').read() key = CipherData.unpack_key(packed_key, secret) state.data = {'key': key}
# Prepare parameters for makeCredential rp = {"id": "secrez.io", "name": "secrez.io"} user = {"id": bytes(user_id, encoding='utf-8'), "name": user_name} challenge = bytes(randomString(12), encoding='utf-8') hmac_ext = HmacSecretExtension(client.ctap2) challenge = bytes(randomString(12), encoding='utf-8') allow_list = [{"type": "public-key", "id": credential.credential_id}] assertions, client_data = client.get_assertion({ "rpId": rp["id"], "challenge": challenge, "allowCredentials": allow_list, "extensions": hmac_ext.get_dict(salt), }) assertion = assertions[0] hmac_res = hmac_ext.results_for(assertion.auth_data) secret = b2a_hex(hmac_res[0]).decode("utf-8") print(secret)
pin = None if client.info.options.get('clientPin'): pin = getpass('Please enter PIN:') else: print('no pin') hmac_ext = HmacSecretExtension(client.ctap2) # Create a credential if not use_nfc: print('\nTouch your authenticator device now...\n') attestation_object, client_data = client.make_credential( rp, user, challenge, extensions=hmac_ext.create_dict(), pin=pin) # HmacSecret result: hmac_result = hmac_ext.results_for(attestation_object.auth_data) credential = attestation_object.auth_data.credential_data print('New credential created, with the HmacSecret extension.') # Prepare parameters for getAssertion challenge = 'Q0hBTExFTkdF' # Use a new challenge for each call. allow_list = [{'type': 'public-key', 'id': credential.credential_id}] # Generate a salt for HmacSecret: salt = os.urandom(32) print('Authenticate with salt:', b2a_hex(salt)) # Authenticate the credential if not use_nfc: print('\nTouch your authenticator device now...\n')