{"library":"pyu2f","title":"U2F Host Library","description":"pyu2f is a Python-based U2F host library for Linux, Windows, and MacOS, providing functionality for interacting with U2F devices over USB. The current version is 0.1.5. The library's support is discontinued as U2F is an outdated FIDO specification, with `python-fido2` being the recommended alternative for FIDO2 and U2F backward compatibility.","language":"python","status":"abandoned","last_verified":"Sun May 17","install":{"commands":["pip install pyu2f"],"cli":null},"imports":["from pyu2f import model","from pyu2f.convenience import authenticator"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import os\nfrom pyu2f import model\nfrom pyu2f.convenience import authenticator\n\n# --- Placeholder values for demonstration ---\n# In a real application, these would come from a U2F challenge\n# issued by a relying party (e.g., a web service).\nAPP_ID = 'https://example.com'\nORIGIN = 'https://example.com'\nCHALLENGE_BASE64 = 'some_base64_challenge_data_from_server'\nKEY_HANDLE_BASE64 = 'some_base64_key_handle_from_previous_registration'\n\nprint(\"Attempting U2F authentication...\")\n\ntry:\n    # 1. Prepare registered key and challenge data\n    # The RegisteredKey model requires a base64 encoded key handle.\n    registered_key = model.RegisteredKey(KEY_HANDLE_BASE64.encode('utf-8'))\n    \n    # The challenge data is a list of dictionaries, each containing\n    # a RegisteredKey object and the raw challenge.\n    challenge_data = [{\n        'key': registered_key,\n        'challenge': CHALLENGE_BASE64.encode('utf-8')\n    }]\n\n    # 2. Create the authenticator interface\n    api = authenticator.CreateCompositeAuthenticator(ORIGIN)\n\n    # 3. Authenticate with the U2F device\n    # This will typically prompt the user to touch their security key.\n    response = api.Authenticate(APP_ID, challenge_data)\n\n    if response:\n        print(\"Authentication successful!\")\n        print(f\"Client Data: {response.client_data.decode('utf-8')}\")\n        print(f\"Signature Data: {response.signature_data.decode('utf-8')}\")\n    else:\n        print(\"Authentication failed or timed out.\")\n\nexcept Exception as e:\n    print(f\"An error occurred during authentication: {e}\")\n\n# Optional: Using a custom authenticator plugin via environment variable\n# SK_SIGNING_PLUGIN = '/path/to/your/custom_authenticator_script.py'\n# os.environ['SK_SIGNING_PLUGIN'] = SK_SIGNING_PLUGIN\n# print(f\"Custom authenticator plugin set: {os.environ.get('SK_SIGNING_PLUGIN')}\")\n# Then call Authenticate again. The plugin script must adhere to\n# the specification in customauthenticator.py (refer to source code).\n","lang":"python","description":"This quickstart demonstrates how to perform a U2F authentication (signing) operation using `pyu2f`. It involves creating a `RegisteredKey` object, preparing challenge data, and then calling the `Authenticate` method on a `CompositeAuthenticator` instance. In a real-world scenario, the `APP_ID`, `ORIGIN`, `CHALLENGE_BASE64`, and `KEY_HANDLE_BASE64` values would be dynamically provided by a U2F relying party server after a registration process. Users may be prompted to physically interact with their U2F device. The library also supports offloading signing to a pluggable command-line tool by setting the `SK_SIGNING_PLUGIN` environment variable.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-17","installed_version":"0.1.5","pypi_latest":"0.1.5","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":2.5,"avg_import_s":0.01,"wheel_type":"sdist"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"19.5M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":2.2,"import_time_s":0,"mem_mb":0.2,"disk_size":"20M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"21.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":2.1,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"22M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"11.9M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":3.1,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"11.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":2.8,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"19.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyu2f","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":2.5,"import_time_s":0.01,"mem_mb":0.2,"disk_size":"20M"}]}}