hatamiarash7/go-chat-server

By hatamiarash7

Updated 5 months ago

Simple & Encrypted Chat

Image
Networking
Developer tools
0

877

hatamiarash7/go-chat-server repository overview

Go Chat

Release version Project language Release License Image size

A simple encrypted chat system using a PUB/SUB single channel. Supports PGP and AES-256-GCM end-to-end encryption. Any message sent from a client (publisher) is encrypted and routed to every other client (subscriber) on the channel.

Architecture

All messages are encrypted client-side before being sent to the relay server. The server never sees plaintext — it only routes opaque encrypted payloads between clients.

             ┌────────┐                  ┌────────┐
Message ─────► Client │                  │ Client ├──Decrypt──► Message
             └───┬────┘                  └────▲───┘
                 │                            │
                 │           ┌────────┐       │
                 └─Encrypt───► Server ├───────┘
                             └────────┘

Messages use length-prefixed binary framing (4-byte big-endian header + JSON payload) for reliable delivery over TCP, replacing the previous delimiter-based protocol.

Encryption Modes

ModeAlgorithmTypeKey MaterialBest For
pgpGPG/PGPAsymmetricPublic + Private key filesHigh-security, identity-based
aesAES-256-GCM + Argon2idSymmetricShared passphraseSimple setup, fast encryption
PGP Mode (Default)

Uses public-key cryptography. Each client encrypts with the shared public key and decrypts with the private key + passphrase. Ideal when you need strong identity-based security.

AES-256-GCM Mode

Uses authenticated symmetric encryption with:

  • Argon2id key derivation (memory-hard, 64MB, 3 iterations) from the shared passphrase
  • Random 12-byte nonce per message (no nonce reuse)
  • Authenticated encryption (confidentiality + integrity + tamper detection)

This is the recommended mode for simplicity and performance.

Configure

Configuration is done through environment variables. You can create a .env file in the project root:

START_MODE=server
HOST=localhost
PORT=12345
ENCRYPTION=pgp
PUBLIC_KEY_FILE=./keys/public.asc
PRIVATE_KEY_FILE=./keys/private.asc
PASSPHRASE=your-secure-passphrase
VariableDescriptionDefaultRequired
START_MODEApplication modeYes (server or client)
PORTTCP port12345No
HOSTBind/connect addresslocalhostNo
ENCRYPTIONEncryption algorithmpgpNo (pgp or aes)
PUBLIC_KEY_FILEPath to PGP public keyPGP mode only
PRIVATE_KEY_FILEPath to PGP private keyPGP mode only
PASSPHRASEPGP key passphrase or AES shared secretClient mode

Note: Escape any special characters in PASSPHRASE when using shell commands.

Key Generation

PGP Keys

Generate a PGP key pair using GPG:

# Generate a new key pair (follow the prompts)
gpg --full-generate-key

# List your keys to find the key ID
gpg --list-keys

# Export public key (replace KEY_ID with your key ID or email)
gpg --armor --export KEY_ID > keys/public.asc

# Export private key
gpg --armor --export-secret-keys KEY_ID > keys/private.asc

Quick generation (non-interactive, for testing):

mkdir -p keys

# Generate key with predefined settings
gpg --batch --gen-key <<EOF
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: Go Chat User
Name-Email: [email protected]
Expire-Date: 0
Passphrase: your-secure-passphrase
%commit
EOF

# Export keys
gpg --armor --export [email protected] > keys/public.asc
gpg --armor --export-secret-keys [email protected] > keys/private.asc

Warning

You can't use PGP keys on smart-cards like YubiKey because the `gopenpgp` requires raw private key material in memory.
AES Mode (No Key Files Needed)

For AES-256-GCM mode, only a shared passphrase is needed:

# All clients must use the same passphrase
export ENCRYPTION=aes
export PASSPHRASE="a-strong-shared-secret-at-least-16-chars"

Generate a strong random passphrase:

# Using openssl
openssl rand -base64 32

# Using /dev/urandom
head -c 32 /dev/urandom | base64

Usage

Binaries

Download the latest release from the releases page.

Server:

START_MODE=server PORT=12345 ./go-chat

Client (PGP):

START_MODE=client ENCRYPTION=pgp \
  PUBLIC_KEY_FILE=./keys/public.asc \
  PRIVATE_KEY_FILE=./keys/private.asc \
  PASSPHRASE="your-passphrase" \
  HOST=server-address PORT=12345 \
  ./go-chat

Client (AES):

START_MODE=client ENCRYPTION=aes \
  PASSPHRASE="shared-secret" \
  HOST=server-address PORT=12345 \
  ./go-chat

Client Commands:

  • Type a message and press Enter to send
  • /quit or /exit to disconnect
  • Ctrl+C for graceful shutdown

Note: For macOS, you may need to allow the binary: System Preferences > Security & Privacy > General > Open Anyway.

Docker

Run the server in a Docker container:

docker run -it -p 12345:12345 hatamiarash7/go-chat-server

With custom settings:

docker run -it -p 9999:9999 \
  -e PORT=9999 \
  -e HOST=0.0.0.0 \
  hatamiarash7/go-chat-server

The Docker image defaults: HOST=0.0.0.0, PORT=12345, START_MODE=server.

Build from source
# Build
make build

# Run server
make server

# Run client (set env vars first or create .env)
make client

# Show version
./go-chat --version

Development

# Run all tests with race detection
make test

# Run tests with coverage report
make coverage

# Format code
make fmt

# Run go vet
make vet

# Run all checks (format + vet + test)
make check

# Build Docker image
make docker-build

# Tidy dependencies
make deps

Project Structure

.
├── cmd/
│   └── go-chat/
│       └── main.go              # Application entrypoint
├── internal/
│   ├── client/
│   │   └── client.go            # Chat client implementation
│   ├── config/
│   │   ├── config.go            # Configuration management
│   │   └── config_test.go       # Config tests
│   ├── encryption/
│   │   ├── encryption.go        # Encryptor interface
│   │   ├── aes.go               # AES-256-GCM implementation
│   │   ├── pgp.go               # PGP implementation
│   │   └── encryption_test.go   # Encryption tests
│   ├── message/
│   │   ├── message.go           # Message framing protocol
│   │   └── message_test.go      # Message tests
│   ├── server/
│   │   ├── server.go            # Relay server implementation
│   │   └── server_test.go       # Server tests
│   └── version/
│       └── version.go           # Build-time version info
├── .dockerignore
├── .env.example
├── .gitignore
├── Dockerfile
├── go.mod
├── go.sum
├── LICENSE
├── Makefile
└── README.md

Support

Donate with Bitcoin Donate with Ethereum

ko-fi

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

Issues

Each project may have many problems. Contributing to the better development of this project by reporting them. 👍

Tag summary

Content type

Image

Digest

sha256:0c62de859

Size

1.9 MB

Last updated

5 months ago

docker pull hatamiarash7/go-chat-server