security-encryption

pluginagentmarketplace's avatarfrom pluginagentmarketplace

Game server security including encryption, anti-cheat, and secure communication

⭐1stars🔀0forks📁View on GitHub🕐Updated Dec 31, 2025

When & Why to Use This Skill

This Claude skill provides a comprehensive framework for securing game server architectures, focusing on end-to-end encryption, anti-cheat mechanisms, and secure communication protocols. It offers production-ready implementations for TLS/DTLS transport security, authoritative server models to prevent client-side manipulation, and statistical detection systems for identifying aimbots and speed hacks. By integrating JWT authentication and robust rate limiting, it ensures game infrastructure remains resilient against unauthorized access and DoS attacks.

Use Cases

  • Implementing high-performance TLS 1.3 and DTLS encryption to secure real-time game traffic between clients and servers.
  • Developing authoritative server logic to validate player movement and combat actions, effectively neutralizing speed hacks, wall hacks, and teleportation.
  • Deploying statistical anti-cheat systems that analyze player behavior to detect inhuman reaction times and aimbot patterns.
  • Securing game APIs and player sessions using JWT-based authentication and multi-layered rate limiting to prevent brute-force and DoS attacks.
  • Setting up comprehensive security observability with specialized metrics for tracking security violations and encryption performance.
namesecurity-encryption
descriptionGame server security including encryption, anti-cheat, and secure communication
sasmp_version"1.3.0"
version"2.0.0"
bonded_agent01-game-server-architect
bond_typeSECONDARY_BOND
typecounter
enum[aes_256_gcm, chacha20_poly1305, rsa_4096]
default24
min1
max720
max_attempts1
fallbackreject_connection
levelwarn
fields[event_type, source_ip, threat_level]
- namerate_limit_hits

Security & Encryption for Game Servers

Implement secure game server architecture with encryption and anti-cheat measures.

Security Layers

[Client] ← TLS 1.3 → [Load Balancer] ← mTLS → [Game Server]
                                                    ↓
                                          [Encrypted State]

Transport Security

TLS/SSL Configuration

#include <openssl/ssl.h>

SSL_CTX* createSecureContext() {
    SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());

    // TLS 1.3 only
    SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
    SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);

    // Load certificates
    SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM);
    SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM);

    // Secure cipher suites only
    SSL_CTX_set_ciphersuites(ctx,
        "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256");

    // Enable session tickets
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);

    return ctx;
}

DTLS for UDP Game Traffic

SSL_CTX* createDTLSContext() {
    SSL_CTX* ctx = SSL_CTX_new(DTLS_server_method());
    SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);

    // Cookie verification to prevent DoS
    SSL_CTX_set_cookie_generate_cb(ctx, generateCookie);
    SSL_CTX_set_cookie_verify_cb(ctx, verifyCookie);

    return ctx;
}

Server Authority Model

// NEVER trust client data - validate everything server-side
class AuthoritativeServer {
public:
    bool onMoveCommand(uint32_t playerId, Vector3 targetPos) {
        auto& player = players[playerId];
        Vector3 currentPos = player.position;

        // Validate movement speed
        float distance = (targetPos - currentPos).length();
        float maxDistance = player.speed * deltaTime * 1.1f; // 10% tolerance

        if (distance > maxDistance) {
            logSuspicious(playerId, "SPEED_HACK", {
                {"distance", distance},
                {"max_allowed", maxDistance}
            });
            return false;
        }

        // Validate path (no teleporting through walls)
        if (!isPathClear(currentPos, targetPos)) {
            logSuspicious(playerId, "WALL_HACK", {});
            return false;
        }

        // Apply validated movement
        player.position = targetPos;
        return true;
    }

    bool onFireCommand(uint32_t playerId, Vector3 aimDir) {
        auto& player = players[playerId];

        // Validate fire rate
        auto now = Clock::now();
        auto timeSinceLastShot = now - player.lastFireTime;

        if (timeSinceLastShot < player.weapon.fireRate) {
            logSuspicious(playerId, "FIRE_RATE_HACK", {});
            return false;
        }

        // Server performs hit detection
        auto hit = raycast(player.position, aimDir);
        if (hit.entity) {
            applyDamage(hit.entity, player.weapon.damage);
        }

        player.lastFireTime = now;
        return true;
    }
};

Anti-Cheat Detection

class AntiCheatSystem {
    struct PlayerStats {
        float avgAccuracy;
        float avgReactionTime;
        int suspicionScore;
        std::vector<SuspiciousEvent> events;
    };

    std::unordered_map<uint32_t, PlayerStats> stats;

public:
    void onHit(uint32_t shooter, uint32_t target, const HitInfo& info) {
        auto& s = stats[shooter];

        // Statistical aimbot detection
        updateAccuracy(s, info);
        if (s.avgAccuracy > 0.95f && s.shots > 100) {
            s.suspicionScore += 10;
            flagForReview(shooter, "STATISTICAL_AIMBOT");
        }

        // Inhuman reaction time detection
        if (info.reactionTime < 0.1f) { // 100ms
            s.suspicionScore += 5;
            s.events.push_back({
                "INHUMAN_REACTION",
                info.reactionTime,
                Clock::now()
            });
        }

        // Trigger ban review if threshold exceeded
        if (s.suspicionScore > 100) {
            triggerBanReview(shooter, s);
        }
    }

    void validatePacket(uint32_t playerId, const Packet& pkt) {
        // Check sequence numbers for replay attacks
        if (pkt.sequence <= lastSequence[playerId]) {
            logSuspicious(playerId, "REPLAY_ATTACK", {});
            return;
        }

        // Verify packet checksum
        if (!verifyChecksum(pkt)) {
            logSuspicious(playerId, "PACKET_TAMPERING", {});
            disconnectPlayer(playerId);
        }
    }
};

Authentication

#include <jwt-cpp/jwt.h>

class AuthService {
    std::string secret;

public:
    std::string generateToken(const Player& player) {
        return jwt::create()
            .set_issuer("game-auth-server")
            .set_type("JWS")
            .set_payload_claim("player_id", jwt::claim(player.id))
            .set_payload_claim("username", jwt::claim(player.username))
            .set_issued_at(std::chrono::system_clock::now())
            .set_expires_at(std::chrono::system_clock::now() +
                           std::chrono::hours(24))
            .sign(jwt::algorithm::hs256{secret});
    }

    std::optional<PlayerClaims> validateToken(const std::string& token) {
        try {
            auto verifier = jwt::verify()
                .allow_algorithm(jwt::algorithm::hs256{secret})
                .with_issuer("game-auth-server");

            auto decoded = jwt::decode(token);
            verifier.verify(decoded);

            return PlayerClaims{
                decoded.get_payload_claim("player_id").as_string(),
                decoded.get_payload_claim("username").as_string()
            };
        } catch (const std::exception& e) {
            return std::nullopt;
        }
    }
};

Rate Limiting

class RateLimiter {
    struct Bucket {
        int tokens;
        std::chrono::steady_clock::time_point lastRefill;
    };

    std::unordered_map<std::string, Bucket> buckets;
    std::shared_mutex mutex;

public:
    bool allow(const std::string& key, int cost = 1) {
        std::unique_lock lock(mutex);

        auto& bucket = buckets[key];
        refill(bucket);

        if (bucket.tokens >= cost) {
            bucket.tokens -= cost;
            return true;
        }
        return false;
    }

private:
    void refill(Bucket& bucket) {
        auto now = std::chrono::steady_clock::now();
        auto elapsed = now - bucket.lastRefill;
        auto refillAmount = elapsed.count() * refillRate;
        bucket.tokens = std::min(maxTokens, bucket.tokens + refillAmount);
        bucket.lastRefill = now;
    }
};

// Usage
RateLimiter limiter;

void onClientMessage(Connection* conn, Message& msg) {
    if (!limiter.allow(conn->ip, 1)) {
        // Rate limited
        conn->send(RateLimitedResponse{});
        return;
    }
    processMessage(conn, msg);
}

Rate Limit Thresholds

Action Limit Window
Login attempts 5 1 min
Commands/sec 60 1 sec
Chat messages 10 10 sec
API requests 100 1 min

Troubleshooting

Common Failure Modes

Error Root Cause Solution
TLS handshake fail Cert expired Auto-renew certs
Token rejected Clock drift NTP sync
False positives Strict thresholds Tune detection
DoS vulnerability No rate limit Add rate limiting

Debug Checklist

# Verify TLS configuration
openssl s_client -connect game.example.com:443 -tls1_3

# Check certificate validity
openssl x509 -in server.crt -noout -dates

# Monitor security events
journalctl -u game-server | grep -E "(SUSPICIOUS|BLOCKED|VIOLATION)"

# Test rate limiter
for i in {1..100}; do curl -s game.example.com/api; done

Unit Test Template

#include <gtest/gtest.h>

TEST(Security, RejectsInvalidToken) {
    AuthService auth;
    auto result = auth.validateToken("invalid.token.here");
    EXPECT_FALSE(result.has_value());
}

TEST(Security, DetectsSpeedHack) {
    AuthoritativeServer server;
    Player player{.position = {0, 0, 0}, .speed = 10.0f};

    // Normal movement
    EXPECT_TRUE(server.onMoveCommand(1, {5, 0, 0}));

    // Teleport attempt
    EXPECT_FALSE(server.onMoveCommand(1, {1000, 0, 0}));
}

TEST(Security, RateLimiterWorks) {
    RateLimiter limiter;

    // First 10 requests pass
    for (int i = 0; i < 10; ++i) {
        EXPECT_TRUE(limiter.allow("test_ip"));
    }

    // 11th request blocked
    EXPECT_FALSE(limiter.allow("test_ip"));
}

TEST(Security, AESEncryptDecrypt) {
    std::string plaintext = "game state data";
    auto [ciphertext, iv] = encrypt_aes_gcm(plaintext, key);
    auto decrypted = decrypt_aes_gcm(ciphertext, key, iv);
    EXPECT_EQ(plaintext, decrypted);
}

Resources

  • assets/ - Security checklists
  • references/ - Encryption guides