Big thank you go to UND DREAM Lab for sponsoring this demo! Your donations to Castle Game Engine make our engine sustainable.
Simple 3D viewer that:
-
Displays embedded (in data) 3D files, from glTF, X3D or other model formats. This is mostly just equal to the "New Project -> 3D Model Viewer" project created by the editor.
-
This works on web or any other platform (desktop, mobile, console) supported by Castle Game Engine.
-
On the web, the data is encrypted, to prevent nasty (ab)users from simply downloading the ZIP file with data and unpacking it and stealing your copyrighted data.
Using Castle Game Engine.
In short:
-
The data is encrypted, using the BlowFish algorithm, at building.
-
The web application has embedded key to decrypt, and it's using this key to decrypt the accessed data.
Before using this for your own projects, make sure to customize the password, and also understand the limitations of this approach.
Details what is happening:
-
The build.sh script does everything and is the best overview to understand what happens.
-
We build an application to encrypt in utils/encrypt_data. It can encrypt any file using BlowFish. The password is hardcoded inside utils/encrypt_data/encrypt_data.dpr.
-
Then, for web, we build the regular application (our 3D viewer) and use
encrypt_data
to encrypt the data zip. We rename the old ZIP toviewer_3d_data.zip.not_encrypted_do_not_distribute
and place it outside ofcastle-engine-output/web/dist
. -
At run-time we decrypt the data, with the same algorithm and password. This happens inside the engine code, and is activated by building the project with
CASTLE_WEB_DECRYPT_DATA
symbol (defined in CastleEngineManifest.xml). The exact decryption code, with hardcoded password, is in engine src/files/castleuriutils.pas, find theDecryptZip
routine there. -
If everything works, then when the application runs in the browser, you will see in the browser console (F12) message "Decrypting ZIP..." and otherwise everything will work as usual (you will have 3D viewer). See the screenshot above.
Use your own (and random, well hidden) password!
To use this for your own purposes, naturally you should change the BlowFish password to something completely random and unique to your project. Make sure to update both places where the password is used:
- In utils/encrypt_data/encrypt_data.dpr
- In engine's src/files/castleuriutils.pas (search for
BlowFishKeyPhrase
).
We advise to generate a really random password, not just invent some password in your head. This repository contains an utility to generate such passwords, in utils/generate_random_key/, so just do
cd utils/generate_random_key/
castle-engine compile-run
on the command-line to get random password. Use the resulting sequence as your password.
Finally, to push it one step further: Consider changing the trivial way we store the decryption key. You could construct the key from a few pieces of information, stored in the code, or in other files you download (once we support TCastleDownload on the web ).
-
Note that BlowFish doesn't have any checksum/detection to be able to say, in case of mistakes, some nice message like "It's a wrong password". If you provide wrong password for decryption, then BlowFish will still use it and just produce garbage. The observed result will be just an exception at ZIP reading saying "Corrupted ZIP".
-
The encrypted stream actually contains the
size of original data in bytes
+encrypted stream from BlowFish
. We need to know the original size, because BlowFish encryption + decryption adds some padding at the stream end, which we need to reliably strip to get back the original contents.
Users who just download the ZIP file from the server -- will find that it's not really a ZIP, it's a binary stream. Without the decryption key, they won't be able to use this data in any way.
Even if they know the algorithm used to encrypt (which of course is trivial to discover -- this very README
file documents it, for everyone to see).
But! Please be aware of inherent limitations of this approach. 1. People who are skilled can still obtain your decryption key (no matter how well you hide it). 2. For some use-cases, the people who want to abuse your content can do it even without doing the decryption. So please don't treat this as a magic solution that makes your content inaccessible. It just makes the abuse more difficult (it's no longer a matter of "just download the ZIP with data").
Details:
-
Abusers can decompile/disassemble your WebAssembly application to learn the
BlowFishKeyPhrase
hardcoded there. You can try to make it harder (spread it over multiple constants, treat withxor
with pattern in yet another place, download parts of the key from your server etc.) but ultimately you have to know this value, at some point at run-time, in your application. If someone can run your application and observe the memory, then they can always learn the key. -
People can also use applications like "OpenGL debuggers" to just get "WebGL commands snapshot" that went into rendering a given frame. They can then reproduce 3D models and textures this way, and there's nothing you can do about it, this is possible with absolutely any 3D engine.
Compile by:
-
CGE editor. Just use menu items "Compile" or "Compile And Run".
-
Or use CGE command-line build tool. Run
castle-engine compile
in this directory. -
Or use Lazarus. Open in Lazarus
viewer_3d_standalone.lpi
file and compile / run from Lazarus. Make sure to first register CGE Lazarus packages.