Skip to content

Add cryptography fallback when PyCryptodome (Crypto) is unavailable#1725

Merged
AlexxIT merged 3 commits into
AlexxIT:masterfrom
juanjocop:patch-1
Mar 3, 2026
Merged

Add cryptography fallback when PyCryptodome (Crypto) is unavailable#1725
AlexxIT merged 3 commits into
AlexxIT:masterfrom
juanjocop:patch-1

Conversation

@juanjocop

Copy link
Copy Markdown
Contributor

Summary

On Home Assistant OS (and some other HA Python environments), SonoffLAN can fail to load due to missing/incompatible PyCryptodome imports:

  • from Crypto.Cipher import AES
  • from Crypto.Hash import MD5
  • from Crypto.Random import get_random_bytes

This results in a startup error such as:
cannot import name 'AES' from 'Crypto.Cipher'

What changed

  • Wrap PyCryptodome (Crypto.*) imports in try/except.
  • When imports fail, provide a minimal drop-in fallback based on:
    • cryptography (HA already ships it)
    • hashlib for MD5
    • os.urandom for random bytes

The fallback preserves the existing API used by local.py:

  • AES.new(key, AES.MODE_CBC, iv=iv) returning an object with encrypt()/decrypt()
  • AES.block_size
  • MD5.new().update(...).digest()
  • get_random_bytes(n)

No behavior changes when PyCryptodome is available.

Why

HAOS users cannot install Python dependencies with pip inside the HA container,
so SonoffLAN should degrade gracefully when PyCryptodome is not present.

Testing

  • Verified Home Assistant starts without the Crypto import exception.
  • Verified SonoffLAN loads successfully and LAN encryption/decryption continues to work.

juanjocop and others added 2 commits January 27, 2026 13:21
Home Assistant OS environments may not provide a working `Crypto.*` module
(PyCryptodome), causing SonoffLAN to fail at startup with:
"cannot import name 'AES' from 'Crypto.Cipher'".

This change wraps the PyCryptodome imports in a try/except and provides a
drop-in fallback implementation using the `cryptography` package (already
bundled with Home Assistant) plus `hashlib`/`os`:

- AES-CBC cipher wrapper compatible with `AES.new(..., AES.MODE_CBC, iv=...)`
- `AES.block_size` constant
- `MD5.new()` compatible helper backed by `hashlib.md5`
- `get_random_bytes()` backed by `os.urandom`

The existing local `pad()`/`unpad()` functions are kept unchanged.
@AlexxIT AlexxIT merged commit 26f7ca0 into AlexxIT:master Mar 3, 2026
@AlexxIT

AlexxIT commented Mar 3, 2026

Copy link
Copy Markdown
Owner

Thanks! I don't think there's any point in supporting pycryptodome if cryptography is already included in HA by default.

@AlexxIT AlexxIT added this to the master milestone Mar 3, 2026
@AlexxIT

AlexxIT commented Mar 5, 2026

Copy link
Copy Markdown
Owner

@juanjocop juanjocop deleted the patch-1 branch March 16, 2026 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants