Title: IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) · Issue #1648 · python-kasa/python-kasa · GitHub
Open Graph Title: IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) · Issue #1648 · python-kasa/python-kasa
X Title: IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) · Issue #1648 · python-kasa/python-kasa
Description: IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) Bug Description HS300 (and possibly other IOT devices) with firmware that requires KLAP v2 authentication fail to connect...
Open Graph Description: IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) Bug Description HS300 (and possibly other IOT devices) with firmware that require...
X Description: IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) Bug Description HS300 (and possibly other IOT devices) with firmware that require...
Opengraph URL: https://github.com/python-kasa/python-kasa/issues/1648
X: @github
Domain: patch-diff.githubusercontent.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2)","articleBody":"# IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2)\n\n## Bug Description\n\nHS300 (and possibly other IOT devices) with firmware that requires KLAP v2 authentication fail to connect with `AuthenticationError: Device response did not match our challenge`. \n\nThe root cause is that `device_factory.py` always uses `KlapTransport` for IOT devices with KLAP encryption, ignoring the `login_version` parameter from discovery. Devices with `login_version=2` require `KlapTransportV2` which uses a different hash algorithm.\n\n## Environment\n\n- python-kasa version: 0.10.2\n- Python version: 3.12\n- OS: Linux (Ubuntu)\n- Device: HS300 Power Strip (hw_ver 2.0)\n\n## Discovery Response\n\nThe device correctly reports `login_version: 2` in discovery:\n\n```python\n{\n 'device_model': 'HS300(US)',\n 'device_type': 'IOT.SMARTPLUGSWITCH',\n 'mgt_encrypt_schm': {\n 'encrypt_type': 'KLAP',\n 'http_port': 80,\n 'lv': 2, # \u003c-- login_version = 2\n },\n ...\n}\n```\n\n## Root Cause\n\nIn `device_factory.py` line 231:\n\n```python\nsupported_device_protocols: dict[str, tuple[type[BaseProtocol], type[BaseTransport]]] = {\n \"IOT.XOR\": (IotProtocol, XorTransport),\n \"IOT.KLAP\": (IotProtocol, KlapTransport), # \u003c-- Always uses KlapTransport (v1)\n \"SMART.AES\": (SmartProtocol, AesTransport),\n \"SMART.KLAP\": (SmartProtocol, KlapTransportV2), # \u003c-- SMART devices use v2\n ...\n}\n```\n\nThe protocol selection key is built from `device_family + encryption_type` only:\n```python\nprotocol_transport_key = protocol_name + \".\" + ctype.encryption_type.value\n```\n\nThe `login_version` is not considered, so all IOT KLAP devices get `KlapTransport` regardless of their actual requirements.\n\n## Hash Algorithm Difference\n\n- **KlapTransport (v1)**: `MD5(MD5(username) + MD5(password))`\n- **KlapTransportV2 (v2)**: `SHA256(SHA1(username) + SHA1(password))`\n\nWhen the wrong transport is used, the handshake hash comparison fails:\n\n```\nExpected auth_hash (KlapTransportV2): 876584dd4d497651c678a8c3d6cb619c...\nActual _local_auth_hash (KlapTransport): 53a1c1366c1e8e04719da24462371caa\n```\n\n## Steps to Reproduce\n\n```python\nimport asyncio\nfrom kasa import Discover, Credentials\n\nasync def main():\n creds = Credentials(\"user@example.com\", \"password\")\n devices = await Discover.discover(\n target=\"10.0.0.255\",\n username=creds.username,\n password=creds.password,\n )\n \n # HS300 with KLAP v2\n if \"10.0.0.110\" in devices:\n dev = devices[\"10.0.0.110\"]\n print(f\"login_version: {dev.config.connection_type.login_version}\")\n print(f\"Transport: {type(dev.protocol._transport).__name__}\")\n \n try:\n await dev.update()\n except Exception as e:\n print(f\"Error: {e}\")\n\nasyncio.run(main())\n```\n\nOutput:\n```\nlogin_version: 2\nTransport: KlapTransport # \u003c-- Should be KlapTransportV2!\nError: Device response did not match our challenge on ip 10.0.0.110...\n```\n\n## Workaround\n\nManually create `IotProtocol` with `KlapTransportV2`:\n\n```python\nfrom kasa.transports.klaptransport import KlapTransportV2\nfrom kasa.protocols import IotProtocol\nfrom kasa.iot import IotStrip\n\n# Create protocol with correct transport\nprotocol = IotProtocol(transport=KlapTransportV2(config=device_config))\ndevice = IotStrip(host=ip, protocol=protocol)\nawait device.update() # Works!\n```\n\n## Suggested Fix\n\nModify `get_protocol()` in `device_factory.py` to check `login_version` for IOT KLAP devices:\n\n```python\ndef get_protocol(config: DeviceConfig, *, strict: bool = False) -\u003e BaseProtocol | None:\n ctype = config.connection_type\n \n # ... existing code ...\n \n # For IOT devices with KLAP and login_version \u003e= 2, use KlapTransportV2\n if (ctype.device_family.value.startswith(\"IOT.\") and \n ctype.encryption_type == DeviceEncryptionType.Klap and\n ctype.login_version is not None and \n ctype.login_version \u003e= 2):\n return IotProtocol(transport=KlapTransportV2(config=config))\n \n # ... rest of existing code ...\n```\n\nOr add a new protocol transport key:\n```python\nsupported_device_protocols = {\n \"IOT.XOR\": (IotProtocol, XorTransport),\n \"IOT.KLAP\": (IotProtocol, KlapTransport),\n \"IOT.KLAP.V2\": (IotProtocol, KlapTransportV2), # \u003c-- New\n ...\n}\n```\n\n## Additional Context\n\nThis issue appeared after a power outage caused the HS300 devices to reboot. The devices had been updated to newer firmware that uses KLAP v2 authentication. Before the reboot, existing sessions may have been cached, masking the issue.\n\nThe same credentials work correctly in the official Kasa app, confirming the credentials are valid.\n\n---\n\n**Related**: This may affect other IOT devices (not just HS300) that have been updated to firmware requiring KLAP v2.\n","author":{"url":"https://github.com/lasdolphin","@type":"Person","name":"lasdolphin"},"datePublished":"2026-01-23T19:20:29.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":2},"url":"https://github.com/1648/python-kasa/issues/1648"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:7fee6a93-7467-4188-23e3-73d01cd3e510 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E1EC:75848:25AA2FD:32C085D:6981CA89 |
| html-safe-nonce | e91a7e2815bb23a30f1b54502a37ba822d0a961937c57e20e0520aa3f4e24582 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFMUVDOjc1ODQ4OjI1QUEyRkQ6MzJDMDg1RDo2OTgxQ0E4OSIsInZpc2l0b3JfaWQiOiI4MzY2ODgxMTE5NDI5MzE1MjA5IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | faaa844e14baa956ce8d3675f6f761079d97a4a9814b4a0af3c905f9d6010d94 |
| hovercard-subject-tag | issue:3848828070 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python-kasa/python-kasa/1648/issue_layout |
| twitter:image | https://opengraph.githubassets.com/d765bbd3ab117351249e4824cea17079438fe012f9a9d7406b429d4bd1636bcb/python-kasa/python-kasa/issues/1648 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/d765bbd3ab117351249e4824cea17079438fe012f9a9d7406b429d4bd1636bcb/python-kasa/python-kasa/issues/1648 |
| og:image:alt | IOT devices with KLAP encryption and login_version=2 use wrong transport (KlapTransport instead of KlapTransportV2) Bug Description HS300 (and possibly other IOT devices) with firmware that require... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | lasdolphin |
| hostname | github.com |
| expected-hostname | github.com |
| None | 95dd6eb30a064b87bd2c653e622fe2eb6a2ec1d12751c5463c252220548e75a4 |
| turbo-cache-control | no-preview |
| go-import | github.com/python-kasa/python-kasa git https://github.com/python-kasa/python-kasa.git |
| octolytics-dimension-user_id | 57733869 |
| octolytics-dimension-user_login | python-kasa |
| octolytics-dimension-repository_id | 221571611 |
| octolytics-dimension-repository_nwo | python-kasa/python-kasa |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 221571611 |
| octolytics-dimension-repository_network_root_nwo | python-kasa/python-kasa |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7f9fe298cbc605034955dde47054b68dbf531efd |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width