Why a native extension? An honest comparison with the ionCube approach
Why a PHP-level decryptor is not enough, what ionCube does well, and why we wrote our own C extension — with the trade-offs spelled out.
At the heart of OnionZero sits ozguard, a native PHP extension that decrypts encrypted PHP files at compile time. "Why go to that trouble — was there really no other way?" This post answers that: what the competing approaches do well and which trade-offs we consciously accepted.
Option 1 — Pure-PHP obfuscation
Tools that rename variables and functions or wrap code in layers of eval are cheap and need no extension install. But since the decryption logic itself is PHP, both the key and the decryptor live inside code the customer can reach. For a determined developer this is a speed bump, not a wall.
Option 2 — ionCube (and similar commercial encoders)
Credit where it's due: ionCube is the most battle-tested commercial application of the zend_compile_file technique, with more than two decades behind it, a free loader on the customer side and broad PHP version support. We evaluated ionCube seriously at the start of the project and documented a hybrid workflow for those who want one.
Three reasons pushed us to write our own extension:
- Device-bound key derivation: we wanted files to open only on a specific machine; tying key derivation to the machine fingerprint requires full control over the compile layer.
- Offline-first design: our audience ships products into air-gapped networks. License signature verification, file decryption and update application all had to live under one roof, with no network assumption.
- Price and control: encoder licenses and per-account pricing leave small teams little room. With our own stack we offer customers one quote and one panel.
The native extension has a cost, too
Honesty is the point of this post: ozguard requires php.ini access on the customer server. Extension installation is not possible on locked-down shared hosting; a VPS, dedicated server or container is the target. Each PHP version and platform needs its own build — today Windows (PHP 8.3, NTS x64) and Linux builds exist. We accept that effort in return for moving both the key and the decryptor entirely out of the PHP level.
No claim of being unbreakable
Any seller-hidden content running on a local machine is theoretically solvable given enough time and access — true for ionCube and true for us. Our goal is not impossibility but making the cost of breaking exceed the value of copying: random per-file keys, in-memory decryption, device binding and tamper detection together move the target to "buying the product is cheaper than reading the source".
A native extension is not a vanity project; it is an architectural decision that moves the control surface from inside PHP into the engine itself.