
Tenda Technology Co., Ltd NVR_4H: CH3 v2.1.V27.5.58.6 was discovered to contain a hardcoded cryptographic key.
CNVD ID: CNVD-2026-25884
Vendor: Tenda Technology Co., Ltd.
Product: NVR_4H network video recorder (hardware version CH3V2.1)
Firmware: V27.5.58.6
Class: CWE-321 — Use of Hard-coded Cryptographic Key
The NVR_4H firmware stores an ECDSA key pair in its read-only user-x.squashfs partition (mounted at /opt/app/): the private key in /etc/privkey.pem and the matching self-signed certificate in /etc/cacert.pem. Both were generated once at build time and baked into the image, so every device running V27.5.58.6 ships with the same private key.
The firmware image is a free download from Tenda's website. Anyone who unpacks it holds a working private key for the HTTPS interface of every NVR_4H on this version. An attacker on the same network (LAN, Wi-Fi, or an internet-facing device) can put a proxy between the admin's browser and the NVR via ARP spoofing or DNS poisoning, present the genuine Tenda certificate with the extracted key, and the browser will not show any warning. The full session is then readable and modifiable in real time: admin login, session tokens, camera RTSP credentials, device configuration.
| File | Description |
|---|---|
/etc/privkey.pem | 302-byte EC private key (P-256) |
/etc/cacert.pem | 802-byte self-signed certificate, O=Tenda, OU=Video Surveillance, CN=www.tenda.com.cn |
The firmware container is a ZIP archive at offset 0xBBB:
# 1. unpack the firmware
binwalk -e ted.bin
cd ted.bin.extracted/BBB
# 2. strip the 64-byte proprietary header
dd if=user-x.squash.img of=pure_system.squashfs bs=1 skip=64
# 3. unpack the filesystem
unsquashfs pure_system.squashfs
# 4. locate the key material
find squashfs-root -name "*.pem"
# squashfs-root/etc/cacert.pem
# squashfs-root/etc/privkey.pem
To confirm the private key belongs to the shipped certificate, export the public key from both and compare:
openssl ec -in squashfs-root/etc/privkey.pem -pubout > pub_from_priv.pem
openssl x509 -in squashfs-root/etc/cacert.pem -pubkey -noout > pub_from_cert.pem
diff pub_from_priv.pem pub_from_cert.pem
# no output
sha256sum pub_from_priv.pem pub_from_cert.pem
# 80b6aa4b9e8f4cd30e857ff5b9bfcf7e0227e268f4d397efdaffe37d4b0e9bcc (both files)
The key also works straight out of the image:
openssl s_server \
-key squashfs-root/etc/privkey.pem \
-cert squashfs-root/etc/cacert.pem \
-accept 4433 -www
# ACCEPT — TLS server starts with no errors
user-x.squashfs is a compressed read-only filesystem, so its content is byte-identical on every unit shipped.
There is no per-device provisioning anywhere in the image: no init scripts, no openssl binary, no first-boot key generation. The only keygen-related strings in the whole filesystem come from hostapd and wpa_supplicant, which have nothing to do with the HTTPS server.
/etc/ inside the squashfs contains just four files, two of which are this key material. Both carry the squashfs build timestamp rather than a runtime one.
The certificate is X.509 v1, self-signed (issuer = subject = C=CN, ST=ZJ, L=HZ, O=Tenda, OU=Video Surveillance, CN=www.tenda.com.cn), valid 1999-12-31 to 2049-12-18, with no SAN and no key usage extensions. The serial 1c:f2:13:a0:7b:e2:7c:91:63:f3:e0:0c:be:0f:0d:42:2e:6b:e8:69 is fixed and identical across all devices.
The extracted private key, usable as-is:
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHQLiI/KUzk/hXX4BZVuujlQMit341WWi3sTpLlGQVcaoAoGCCqGSM49
AwEHoUQDQgAEqFt550/3k/nGoYr4CFeRtvDf9HuZpHbb5FecKweJtFH7a5hBNFqq
qckxILVt8KefGENelZgPdEGNU6VcXyTORA==
-----END EC PRIVATE KEY-----
Confidentiality and integrity of the entire HTTPS management interface are lost for every device on this firmware version, against anyone who has downloaded the public image. No privileges and no user interaction are needed on the target side — a passive MITM is enough. Stolen admin credentials give full control of the recorder and its cameras.
Generate a unique key pair per device on first boot and store it on a writable partition (e.g. the JFFS2 area under /opt/sav/), and remove privkey.pem and cacert.pem from the read-only image entirely. Longer term, issue per-device certificates signed at manufacturing time.