# Common Pitfalls **Domain:** Custom encrypted archiver with busybox/Kotlin decompression **Researched:** 2026-02-24 **Confidence:** HIGH ## Critical Pitfalls ### Pitfall 1: Busybox OpenSSL Cipher Availability **What:** Target busybox may not have the chosen cipher. GCM, ChaCha20 are likely unavailable. **Prevention:** Test `busybox openssl enc -ciphers` on actual device FIRST. Use AES-256-CBC (universally available). **Phase:** Phase 1 (format design) — blocking decision. ### Pitfall 2: Endianness Mismatch Across Platforms **What:** Inconsistent byte order between Rust (x86_64), Kotlin (ARM64), shell (xxd parsing). **Prevention:** Use little-endian everywhere. Rust: `to_le_bytes()`. Kotlin: `ByteBuffer.order(LITTLE_ENDIAN)`. Document in format spec. **Phase:** Phase 1 (format design). ### Pitfall 3: PKCS7 Padding Incompatibility **What:** Different padding handling between Rust crates, javax.crypto, and busybox openssl causes last-block corruption. **Prevention:** Store exact compressed-data length in header. Use `-nopad` in openssl and truncate manually, OR let openssl handle padding with `-K`/`-iv` flags. Test with non-16-byte-aligned data. **Phase:** Phase 2 (encryption implementation). ### Pitfall 4: OpenSSL Key Derivation (EVP_BytesToKey vs Raw Key) **What:** busybox `openssl enc` derives keys via EVP_BytesToKey by default. Rust/Kotlin use raw keys. Decryption produces garbage. **Prevention:** Use `-K HEX -iv HEX -nosalt` flags for raw key mode. Test on target device FIRST. This is the #1 failure mode. **Phase:** Phase 1 (format design) — blocking. ### Pitfall 5: Shell Arithmetic Overflow with Large Files **What:** busybox `sh` arithmetic may be 32-bit signed, overflowing at 2GB offsets. **Prevention:** Use `dd bs=4096` with block-count math. Limit archive size in spec. Test with >50MB archives. **Phase:** Phase 1 (format) + Phase 5 (shell decoder). ### Pitfall 6: IV/Nonce Reuse with Hardcoded Key **What:** Same key + same IV = identical ciphertext for identical files. Information leak. **Prevention:** Random 16-byte IV per file, stored in cleartext alongside ciphertext. Never deterministic IV. **Phase:** Phase 2 (encryption). ### Pitfall 7: Busybox xxd Behavioral Differences **What:** busybox `xxd` may not support all GNU xxd flags. Key/IV hex conversion fails silently. **Prevention:** Use only `xxd -p` and `xxd -r -p`. Test on actual device. Fallback: `od -A n -t x1`. **Phase:** Phase 5 (shell decoder). ## Moderate Pitfalls ### Pitfall 8: APK Files Don't Compress **What:** APKs are already ZIP-compressed. Gzip makes them larger. **Prevention:** Per-file compression flag. Skip compression if output >= input. **Phase:** Phase 2 (compression). ### Pitfall 9: Missing Integrity Verification **What:** No checksums = silent data corruption from bit flips during transfer. **Prevention:** SHA-256 checksum per file. Verify AFTER decompression in all three decoders. **Phase:** Phase 1 (format) + all decoder phases. ### Pitfall 10: Over-Engineering Obfuscation **What:** Complex obfuscation (block shuffling, fake headers) triples implementation complexity with minimal security gain against casual users. **Prevention:** AES encryption IS obfuscation. Custom magic bytes + encrypted payload is sufficient. Keep it simple. **Phase:** Phase 1 (format design). ### Pitfall 11: Rust/Kotlin Crypto Output Incompatibility **What:** "Same algorithm" produces different bytes due to framing differences (IV placement, padding). **Prevention:** Define wire format explicitly: `[16-byte IV][PKCS7-padded ciphertext]`. Golden test vectors mandatory. **Phase:** Phase 2 (encryption). ### Pitfall 12: Android Filesystem Permissions **What:** Extracted files land in wrong location or have wrong permissions on Android. **Prevention:** Store only relative paths. Don't store Unix permissions. Let each decoder handle permissions. **Phase:** Phase 4 (Kotlin decoder). ## Minor Pitfalls - **#13:** Flush/sync writes in shell script — use `sync` after critical files - **#14:** Missing version field — add 1-2 byte version after magic bytes (non-negotiable) - **#15:** Testing only ASCII filenames — include Cyrillic test files - **#16:** Hardcoded key visible in `strings` — store as byte array, split hex fragments in shell ## Key Insight **The busybox shell constraint drives everything.** Every format decision must be validated against "can busybox sh + dd + xxd + openssl actually implement this?" Build shell decompressor prototype EARLY, not last. ## Phase Mapping | Phase | Critical Pitfalls | Action | |-------|------------------|--------| | Format design | #1, #2, #4, #5, #10, #14 | Test busybox on device. Write format spec. Keep it simple. | | Encryption | #3, #6, #8, #11 | Golden test vectors. Random IV. Per-file compression flag. | | Kotlin decoder | #11, #12 | Explicit wire format. Test on device. | | Shell decoder | #1, #4, #5, #7, #15 | Busybox compatibility suite. Large file tests. |