Looking for a way to edit a GLB file as a string in runtime

Good Day,

I have a usecase where I have edited a GLB model using a hex editor. I have added some ciphers into the file and Saved it.

In Threejs code, I am looking for a way to decode the cipher by performing a edit on the GLB model considering it as a binary file.

I am not able to implement any methods that reads the GLB and perform edits in it.

Please suggest a way.

Thank you

I’m curious now^^. Do you mind explaining your use case a bit? I really wonder why anybody would manipulate an asset like that?

three.js can’t help you with that task. It seems you have to load the asset as an array buffer and then manipulate the raw binary data with the respective ArrayBuffer/TypedArray API.

So my current scenario is,

I have a client’s server in to which the Threejs project will be hosted. To perform the hosting, The Client has told me to handover the project to a middleman (Web hosting service provider).

I found a way to Obfuscate the code, But I don’t want the 3D model (GLB file) to be open for the Middleman to go and look around.

So, I used “Hexed” to edit the glb file by changing some texts and exporting the file. If I redo the same edit in the file, It starts to work again.

This same process I want to implement a process by which the Threejs code decodes and performs the edits and then performs loader.

This way, Even if the Middleman gets access to the GLB model, It won’t open unless he knows where the Binary is edited.

So you are looking for a solution to store encrypted assets on a third party server. Browsers which open your application should be able to decrypt the loaded asset in JavaScript to view it correctly. Is that right?

Yes exactly, Ultimate goal is a good encrypted non-usable (by third party) glb file.

Partial result would be atlease the model not appear in the Chrome inspected (Network inspection) - This might not be possible

Since the glb asset is a binary file, it should be possible to use any JavaScript library for encrypting/decrypting binary data. Not even sure a library is necessary since the modern Web Crypto API looks ideal for this use case. On the other hand, it’s a low level API and a library might be easier to use.

@donmccurdy What do you think about this topic? I could image other devs already looked for the same thing.

I tried a handfull of JS modules from the Internet, Nothing seems to work, Mainly in the GLB usecase.

I don’t know much about the Web crypto API, I will look into it.

Also, I am trying another JS module called JSZip to create a zip file and then uncompress it during execution.

JSZip will compress/uncompress the file. AFAIK, it does not support encrypted zip.

Thought it would unzip in the background without revealing the model in the Chrome network inspector.

Also noticed that unzipping is not a easy work, My project is simple vanilla JS. Ditching the zip idea because it requires node.

Would it be possible for you to generate a sandbox with Web crypto API (or) Is it possible for you to provide me with the way to convert the GLB into an arraybuffer (or) convert the file into a JSON from which threejs can load the scene.

This whole process is very complex and tricky.

Sorry, I can’t provide you an implementation for this task.

It’s probably better to just use this topic to find out and investigate approaches for properly encrypting/decrypting glTF assets. As mentioned above, I would probably start with the Crypto API and see how it goes.

Righto, I will look into that.

Thanks, Lets see if any other member provides some more insights.

Maybe I’m mistaken but isn’t a draco compressed model practically unusable in terms of getting it back to an editable model? Can btoa to retrieve the base 64 of the model help at all?

Nope, I just tried compressing my GLB model to a Draco Compressed one, Its easily opening in Blender.

1 Like

Damn I must have an older blender

I would suggest setting aside GLB for a moment — generate a Uint8Array with some simple string content…

const binary = new TextEncoder().encode('hello world');

… and try to use whatever libraries or APIs are needed to encrypt that on the server and decrypt it on the client. once you have something that correctly decrypts the binary data, you’ll be able to do this and get the same string back:

const text = new TextDecoder().decode(binary);

From there, exactly the same method will work fine for a binary file containing GLB data.

1 Like

Yeah, Saw a similar thread which says the user was using Blender 2.7x

I took this and tried to implement, I got the arraybuffer (although the texts are gibberish), The saved arraybuffer size is almost a 70% more than my glb model…btw, I saved it as a JSON.

Is this supposed to happen?

I was reading through this post (Again…This time more thoroughly), I wonder if there is a any similar binary handlers available in Threejs?

Post : This is how I protect my 3D models - Help & Support - PlayCanvas Discussion

Compare these:

const text = 'hello world';
const binary = new TextEncoder().encode(text);

console.log(text.length, binary.length); // 11, 11

They’ll be the same for most text content. Certain special characters will increase the length by a few bytes, but if you get a 70% increase something is wrong.

three.js does not deal with encryption, that would need to be handled before you pass the data into three.js loaders.

In general saving with Blender’s “glTF Embedded” option is a 33% waste of space, use “glTF Binary” (.glb) or “glTF Separate” if you’re looking to minimize size.