Step by step encryption of a Lua script - EstevanTH/GMod_Momo_Encryption_Library GitHub Wiki

The guide will help you through the process of encrypting a shared or a client Lua script.

I will try to be clear and easy, but if you have any problem while trying to understand, please post an issue.

I will not deal with encrypted Lua files that include other encrypted Lua files.

Every console command that I tell you to run is always to be entered in the server's console.

For now I'm a little lost with how to include encrypted files stored in the gamemodes folder. I do not recommend to place them there until I figure out how to include them.

Steps

Step 1: Adapt your Lua scripts

You need to make sure that your scripts can be encrypted.

  • Supported scripts are: autorun, autorun/client, gamemode, entities, weapons.
  • You need to split parts that can be encrypted and parts that cannot be into 2 different Lua files.

You need to understand that encrypted files will by loaded by the client after startup because decryption information will arrive late.

Note that, for clientside encrypted files:

  • GM / hook.Add() / ENT / SWEP hooks that happen at initialize time will be ignored because they will be loaded late.
  • gamemode / entities / weapons scripts require an additional header before encryption, because they won't be loaded in the same context they usually are otherwise.

See How to adapt Lua scripts?.

Step 2: Move files that you want to encrypt

Now it's time to move your non-encrypted files into a safe folder, outside of Lua folders.
You can choose garrysmod/momo_encryption/myaddon/. Do not forget to create that folder.
Do not use the garrysmod/data folder because it's writable from the game!

By doing this, you keep clear files for future edits in a safe place.

Step 3: Generate a key

For safety, avoid reusing keys and do your best to make them unique. This applies when you update a file, when you change encryption method and when you encrypt different files.

To generate a new key, type in the console and copy-paste the returned value in your text editor:

lua_run print( momo_encryption.CreateKey( bits ) )

where bits is the number of bits in the key (default 64, recommended 512).

The length of the key depends on the requirement of the encryption method, when specified. The longer the key is, the safer the encryption will be.

Step 4: Encrypt your Lua file

Now that you have a key and you have the clear Lua file ready, you can proceed with encryption!

Type the following in the console:

lua_run print( momo_encryption.EncryptLuaFile( key, fileName, path, destination, compress, method ) )

where

  • key is the key
  • fileName is the path to your clear Lua file, starting with garrysmod/momo_encryption/myaddon/ in my example
  • path is the search path, which is 'MOD' in my example
  • destination is the path to the encrypted Lua file, relative to garrysmod/data; extension must be .txt for now

and optionally

  • compress is true to enable LZMA compression, false otherwise (not recommended)
  • method is the encryption method (see the list)

If the file is a part of gamemode / entities / weapons, I usually suffix the filename with _protected.

The destination file should have been created. Rename it with the proper .lua extension.

Step 5: Move your encrypted Lua file

Depending on what you have encrypted, move your encrypted Lua file to:

(in an addon)

  • garrysmod/addons/.../lua/protected/gamemodes/.../gamemode/, if original was in garrysmod/addons/.../gamemodes/.../gamemode/
  • garrysmod/addons/.../lua/protected/gamemodes/.../entities/entities/.../, if original was in garrysmod/addons/.../gamemodes/.../entities/entities/.../
  • garrysmod/addons/.../lua/protected/gamemodes/.../entities/weapons/.../, if original was in garrysmod/addons/.../gamemodes/.../entities/weapons/.../
  • garrysmod/addons/.../lua/protected/, if original was in garrysmod/addons/.../lua/autorun/
  • garrysmod/addons/.../lua/protected/client/, if original was in garrysmod/addons/.../lua/autorun/client/
  • garrysmod/addons/.../lua/weapons/.../
  • garrysmod/addons/.../lua/entities/.../

(outside of any addon)

  • garrysmod/lua/protected/gamemodes/.../gamemode/, if original was in garrysmod/gamemodes/.../gamemode/
  • garrysmod/lua/protected/gamemodes/.../entities/entities/.../, if original was in garrysmod/gamemodes/.../entities/entities/.../
  • garrysmod/lua/protected/gamemodes/.../entities/weapons/.../, if original was in garrysmod/gamemodes/.../entities/weapons/.../
  • garrysmod/lua/protected/, if original was in garrysmod/lua/autorun/
  • garrysmod/lua/protected/client/, if original was in garrysmod/lua/autorun/client/
  • garrysmod/lua/weapons/.../
  • garrysmod/lua/entities/.../

Step 6: Make inclusions

There are 2 locations where you can include encrypted files.

Note that because files containing inclusions mention the key, you should NEVER send them to clients, with AddCSLuaFile() or by putting inclusions in a file that is automatically sent to clients!

Calling require( "momo_encryption" ) ensures that the library is loaded before calling momo_encryption.IncludeLuaFile().

Server inclusions happen right when you do them, while client inclusions happen later.

Method 1: Making a list in lua/autorun/server/

Making a list of inclusions in garrysmod/lua/autorun/server/ or garrysmod/addons/.../lua/autorun/server/ is a nice and rather safe idea. It is not very consistent when including gamemode / entities / weapons scripts, but it works well if inclusion order of a shared script serverside is not a problem.

Create a Lua file, for example lua/autorun/server/includes_mysuperaddon.lua, and put this content inside:

require( "momo_encryption" )
momo_encryption.IncludeLuaFile( key, fileName, identifier, includeOnServer, includeOnClient )
momo_encryption.IncludeLuaFile( "5cb7", "protected/superscript.lua", "lua/protected/superscript.lua", true, true )
momo_encryption.IncludeLuaFile( "4eeb8c", "protected/client/winner.lua", nil, false, true )

where

  • key is the encryption key
  • fileName is the encrypted Lua file path (relative to lua/)
  • identifier is the file path displayed in error messages or nil for default value; putting non-printable ASCII characters is recommended
  • includeOnServer is true if the file should be loaded serverside, false otherwise
  • includeOnClient is true if the file should be loaded clientside, false otherwise

followed by a few examples.

Method 2: Including encrypted scripts directly from a gamemode / entities / weapons server Lua file

To be a more consistent with gamemode / entities / weapons encrypted scripts, you can include them directly from a server Lua file that is NOT SENT to clients. This is a little more dangerous because you more likely might accidentally send such server scripts to clients, revealing encryption keys.

Here are a few examples of such files with examples of lines to add:

  • In gamemodes/.../gamemode/init.lua
require( "momo_encryption" )
momo_encryption.IncludeLuaFile( "012345", "protected/gamemodes/.../gamemode/hud_protected.lua", nil, false, true )
  • In gamemodes/.../entities/entities/.../init.lua
require( "momo_encryption" )
momo_encryption.IncludeLuaFile( "123456", "protected/gamemodes/.../entities/entities/.../shared_protected.lua", nil, true, true )
momo_encryption.IncludeLuaFile( "234567", "protected/gamemodes/.../entities/entities/.../client_protected.lua", nil, false, true )
  • In gamemodes/.../entities/weapons/.../init.lua
require( "momo_encryption" )
momo_encryption.IncludeLuaFile( "345678", "protected/gamemodes/.../entities/weapons/.../shared_protected.lua", nil, true, true )
momo_encryption.IncludeLuaFile( "456789", "protected/gamemodes/.../entities/weapons/.../client_protected.lua", nil, false, true )
  • In lua/weapons/.../init.lua
require( "momo_encryption" )
momo_encryption.IncludeLuaFile( "345678", "weapons/.../shared_protected.lua", nil, true, true )
momo_encryption.IncludeLuaFile( "456789", "weapons/.../client_protected.lua", nil, false, true )
  • In lua/entities/.../init.lua
require( "momo_encryption" )
momo_encryption.IncludeLuaFile( "56789a", "weapons/.../shared_protected.lua", nil, true, true )
momo_encryption.IncludeLuaFile( "6789ab", "weapons/.../client_protected.lua", nil, false, true )

Step 7: Finished

The work is finished!

If you are paranoid, you can move folders containing clear Lua files out of the game folder, so they won't be accessible from Lua.

Examples