Files
android-encrypted-archiver/.planning/research/STACK.md
2026-02-24 22:51:05 +03:00

7.1 KiB

Technology Stack

Project: encrypted_archive (Custom Encrypted Archiver) Researched: 2026-02-24 Overall confidence: MEDIUM (versions from training data — verify before use)


Critical Constraint: Three-Platform Compatibility

Every technology choice is constrained by the weakest link: busybox shell. The Rust archiver can use any library, but the format it produces must be decodable by:

  1. Kotlin on Android 13 (javax.crypto / java.security)
  2. busybox shell (openssl, dd, xxd)

This constraint eliminates many otherwise-superior choices.


Encryption

Technology Version Purpose Why Confidence
aes crate ^0.8 AES-256-CBC block cipher busybox openssl supports aes-256-cbc — the critical three-way constraint. Android javax.crypto supports AES natively. HIGH
cbc crate ^0.1 CBC mode of operation Standard mode: openssl CLI aes-256-cbc, javax.crypto AES/CBC/PKCS5Padding HIGH
hmac + sha2 ^0.12 / ^0.10 HMAC-SHA256 integrity Encrypt-then-MAC. busybox openssl dgst -sha256 -hmac. Kotlin Mac("HmacSHA256") HIGH

Why AES-256-CBC over AES-GCM: busybox openssl does NOT support AEAD modes (GCM/CCM) in openssl enc. AES-CBC + HMAC-SHA256 (encrypt-then-MAC) provides equivalent security. CBC is the only AES mode reliably available across all three platforms.

Why NOT ChaCha20-Poly1305: busybox openssl does not support ChaCha20. Android javax.crypto has no standard ChaCha20 support. Would require native libraries, violating constraints.

Why NOT aes-gcm crate: Not decodable via openssl enc in busybox.

Compression

Technology Version Purpose Why Confidence
flate2 crate ^1.0 gzip compression busybox gunzip works natively. Android GZIPInputStream works natively. Simplest cross-platform path. HIGH

Why gzip-wrapped DEFLATE: busybox gunzip handles it. Android GZIPInputStream handles it. flate2 GzEncoder/GzDecoder produces standard gzip.

Why NOT zstd/lz4/brotli: busybox has no decompressors for any of these.

CLI Framework

Technology Version Purpose Why Confidence
clap ^4 CLI argument parsing De facto Rust standard. Derive macros. Subcommands (pack/unpack/inspect). HIGH

Binary Format

Technology Version Purpose Why Confidence
Manual byte-level I/O N/A Custom binary format Using bincode/serde would make format recognizable by forensic tools. Manual bytes give full control for obfuscation. HIGH

Hashing / Integrity

Technology Version Purpose Why Confidence
sha2 crate ^0.10 SHA-256 checksums busybox sha256sum, Android MessageDigest("SHA-256") HIGH

Random / IV Generation

Technology Version Purpose Why Confidence
rand ^0.8 Random IV generation CSPRNG for AES-CBC initialization vectors. Each archive gets unique IV. HIGH

Error Handling

Technology Version Purpose Why Confidence
anyhow ^1 Application errors CLI app, not library. Ergonomic error chains. HIGH
thiserror ^2 Typed format errors Specific errors for format validation, decryption, integrity. MEDIUM

Testing

Technology Version Purpose Why Confidence
Built-in #[test] N/A Unit tests Round-trip pack/unpack/compare HIGH
assert_cmd ^2 CLI integration tests Test actual binary MEDIUM
tempfile ^3 Temp dirs Clean test isolation HIGH

Kotlin/Android Decompressor Stack (Zero External Dependencies)

Technology Source Purpose
javax.crypto.Cipher Android SDK AES-256-CBC: Cipher.getInstance("AES/CBC/PKCS5Padding")
javax.crypto.spec.SecretKeySpec Android SDK 32-byte hardcoded key
javax.crypto.spec.IvParameterSpec Android SDK IV from archive header
javax.crypto.Mac Android SDK HMAC-SHA256: Mac.getInstance("HmacSHA256")
java.util.zip.GZIPInputStream Android SDK Gzip decompression
java.security.MessageDigest Android SDK SHA-256 integrity
java.nio.ByteBuffer Android SDK Little-endian parsing

Busybox Shell Decompressor Stack

Tool Purpose Key Flags
dd Extract byte ranges bs=1 skip=N count=M
xxd Hex encode/decode keys xxd -p
openssl enc AES-256-CBC decrypt -d -aes-256-cbc -K HEX -iv HEX -nosalt
openssl dgst HMAC-SHA256 verify -sha256 -hmac KEY -binary
gunzip Gzip decompress Standard input/output
sha256sum Integrity check -c checksums

Critical: busybox openssl enc uses EVP_BytesToKey by default. MUST pass -K (hex key) + -iv (hex IV) + -nosalt for raw key mode. IV must be in cleartext header.


Cross-Platform Compatibility Matrix

Rust Android SDK busybox Notes
aes+cbc (PKCS7) Cipher("AES/CBC/PKCS5Padding") openssl enc -aes-256-cbc PKCS5=PKCS7 for 16-byte blocks
hmac+sha2 Mac("HmacSHA256") openssl dgst -sha256 -hmac Raw key, not password
flate2 (GzEncoder) GZIPInputStream gunzip Standard gzip
sha2 MessageDigest("SHA-256") sha256sum Hex comparison

Alternatives Considered

Category Recommended Alternative Why Not
Encryption AES-256-CBC + HMAC AES-256-GCM busybox openssl lacks GCM
Encryption AES-256-CBC + HMAC ChaCha20-Poly1305 Not in busybox/Android SDK
Compression flate2 (gzip) zstd No busybox decompressor
Compression flate2 (gzip) lz4 No busybox decompressor
Format Manual bytes bincode/serde Recognizable patterns
Crypto ecosystem RustCrypto (aes+cbc) ring ring bundles C code
Crypto ecosystem RustCrypto (aes+cbc) openssl-rs Unnecessary system dep

Cargo.toml

[package]
name = "encrypted_archive"
version = "0.1.0"
edition = "2021"

[dependencies]
aes = "0.8"
cbc = "0.1"
hmac = "0.12"
sha2 = "0.10"
flate2 = "1.0"
clap = { version = "4", features = ["derive"] }
rand = "0.8"
anyhow = "1"
thiserror = "2"

[dev-dependencies]
assert_cmd = "2"
tempfile = "3"

WARNING: Versions from training data (cutoff May 2025). Verify with cargo search CRATE --limit 1 before use.


Gaps Requiring Verification

  1. Exact latest crate versions (could not verify via crates.io)
  2. Confirm target busybox build includes openssl applet
  3. Confirm xxd availability in target busybox (fallback: od)
  4. Test PKCS7 padding round-trip across all three platforms
  5. Test flate2 GzEncoder output with busybox gunzip and Android GZIPInputStream