{"id":7640,"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.","status":"abandoned","version":"0.1.5","language":"en","source_language":"en","source_url":"https://github.com/google/pyu2f/","tags":["u2f","fido","security key","usb","authentication","hardware security"],"install":[{"cmd":"pip install pyu2f","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Used for Python 2 and 3 compatibility, replaced `python-future` in version 0.1.3.","package":"six"}],"imports":[{"symbol":"model","correct":"from pyu2f import model"},{"symbol":"authenticator","correct":"from pyu2f.convenience import authenticator"}],"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."},"warnings":[{"fix":"Migrate your application to `python-fido2`. Example: `pip install fido2` and adapt your code to the new API.","message":"The `pyu2f` library is officially discontinued and no longer supported. Users are strongly advised to migrate to `Yubico/python-fido2`, which supports both FIDO2 and is backward compatible with U2F devices. Continued use of `pyu2f` may lead to unaddressed security vulnerabilities or compatibility issues.","severity":"breaking","affected_versions":"0.1.5 and earlier"},{"fix":"Transition to solutions built on WebAuthn (like `python-fido2`) for future-proof security key integration, which inherently handles U2F compatibility via CTAP1.","message":"The underlying U2F API in web browsers (e.g., Chrome) has been deprecated in favor of the WebAuthn API. While WebAuthn is backward compatible with U2F devices, this deprecation affects how web applications initiate U2F interactions. Although `pyu2f` is a host library, this trend highlights the obsolescence of the U2F standard itself.","severity":"deprecated","affected_versions":"All versions"},{"fix":"While a 'workaround' of removing return checks for `HidD_GetProductString()` was suggested in an issue, it's not a sustainable fix. This issue indicates platform-specific complexities and may necessitate a switch to a more actively maintained library like `python-fido2` for robust Windows support.","message":"On Windows 10, users might encounter an `OSError: [WinError 50] This request is not supported.` (or similar) when `pyu2f` attempts to enumerate HID devices via `HidD_GetProductString`. This can prevent U2F devices from being detected or used.","severity":"gotcha","affected_versions":"All versions on Windows"},{"fix":"Ensure your project explicitly depends on `six` for Python 2/3 compatibility and update your codebase to Python 3 idioms. If still on Python 2, use `pyu2f` versions compatible with `six` and consider `__future__` imports.","message":"Versions prior to 0.1.2 lacked Python 3 support, and version 0.1.3 replaced `python-future` with `six` for Python 2/3 compatibility. Code written for older Python 2 versions or relying on `python-future` might break or behave unexpectedly in newer Python environments or with `pyu2f` versions 0.1.3 and later.","severity":"breaking","affected_versions":"<= 0.1.2"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Run `pip install pyu2f` to install the library. Ensure your Python environment is correctly activated if using virtual environments.","cause":"The `pyu2f` package is not installed in the current Python environment or the environment is not activated.","error":"ModuleNotFoundError: No module named 'pyu2f'"},{"fix":"This issue is complex and may not have a simple direct fix within `pyu2f`. Consider updating Windows drivers, testing on different Windows versions, or, preferably, migrating to `python-fido2` for more robust and actively maintained hardware interaction.","cause":"This error typically occurs on Windows, specifically within `pyu2f.hid.windows.FillDeviceAttributes`, when attempting to call `HidD_GetProductString` during HID device enumeration. It suggests a low-level interaction issue with the Windows HID API, potentially due to specific device drivers or Windows versions.","error":"OSError: [WinError 50] This request is not supported."},{"fix":"Explicitly decode byte strings (`.decode('utf-8')`) when a string is expected, or encode strings (`.encode('utf-8')`) when bytes are expected, ensuring consistent handling of text data.","cause":"This error can occur in Python 3 when a function expects an iterable (like a string) but receives bytes, often due to incorrect handling of `bytes` vs. `str` differences, especially during decoding/encoding operations that changed between Python 2 and 3.","error":"TypeError: argument of type 'bytes' is not iterable"}]}