Appearance
Native (Crypto)
Access native Rust functions for encryption.
Uses AES-256-GCM for secure encryption.
Methods
isAvailable()
Check if native module is loaded:
javascript
if (gemshell.native.isAvailable()) {
// Native functions available
}getVersion()
Get native module version:
javascript
const version = gemshell.native.getVersion();
// "0.6.0"encrypt(key, text)
Encrypt a string:
javascript
const encrypted = gemshell.native.encrypt('my-secret-key', 'Hello World');
// Returns Base64 encoded ciphertextdecrypt(key, ciphertext)
Decrypt a string:
javascript
const decrypted = gemshell.native.decrypt('my-secret-key', encrypted);
// "Hello World"encryptBytes(key, buffer)
Encrypt a Buffer:
javascript
const data = Buffer.from([1, 2, 3, 4, 5]);
const encrypted = gemshell.native.encryptBytes('my-key', data);decryptBytes(key, buffer)
Decrypt a Buffer:
javascript
const decrypted = gemshell.native.decryptBytes('my-key', encrypted);Key Requirements
- Keys can be any string
- Internally hashed to 256-bit key
- Use strong, unique keys for security
Example: Encrypt Save Data
javascript
module.exports = {
name: 'Save Encryptor',
version: '1.0.0',
settings: [
{ id: 'encryptionKey', type: 'text', label: 'Encryption Key', default: '' }
],
async onModifyAssets(context, settings) {
if (!settings.encryptionKey) {
gemshell.warn('No encryption key set, skipping');
return;
}
// Find save data files
const saveFiles = gemshell.glob('data/*.json');
for (const file of saveFiles) {
const content = gemshell.fs.read(file);
const encrypted = gemshell.native.encrypt(settings.encryptionKey, content);
// Write encrypted version
gemshell.fs.write(file + '.enc', encrypted);
gemshell.fs.remove(file);
gemshell.log(`Encrypted: ${file}`);
}
}
};Example: Protect API Keys
javascript
module.exports = {
name: 'API Key Protector',
version: '1.0.0',
settings: [
{ id: 'masterKey', type: 'text', label: 'Master Key' }
],
async onModifyAssets(context, settings) {
if (!settings.masterKey) return;
// Read config with sensitive data
if (!gemshell.fs.exists('config.json')) return;
const config = gemshell.fs.readJson('config.json');
// Encrypt sensitive fields
if (config.apiKey) {
config.apiKey = gemshell.native.encrypt(settings.masterKey, config.apiKey);
config.apiKeyEncrypted = true;
}
if (config.secret) {
config.secret = gemshell.native.encrypt(settings.masterKey, config.secret);
config.secretEncrypted = true;
}
gemshell.fs.writeJson('config.json', config);
gemshell.log('Sensitive data encrypted');
}
};Security Notes
- Never hardcode keys - Use settings or environment variables
- Use unique keys per game - Don't reuse keys across projects
- AES-256-GCM provides authenticated encryption
- Keys are hashed - Any string works, but longer is better
Decryption in Game
To decrypt at runtime in your game, you'll need to implement decryption in JavaScript or use a library:
javascript
// In your game code (not plugin)
// You'll need a JS crypto library like crypto-js
import CryptoJS from 'crypto-js';
function decrypt(key, ciphertext) {
// Note: This is a simplified example
// The actual format depends on your encryption implementation
const bytes = CryptoJS.AES.decrypt(ciphertext, key);
return bytes.toString(CryptoJS.enc.Utf8);
}Or use the GemCore API if available:
javascript
// Using GemCore native crypto (if exposed)
const decrypted = await gemcore.crypto.decrypt(key, encrypted);