Borg/php/borg-stmf
Claude fe0f85a069
Some checks failed
Go / build (push) Failing after 3s
mkdocs / deploy (push) Failing after 10s
Release / release (push) Failing after 4s
chore: migrate module path from github.com to forge.lthn.ai
Move module declaration and all internal imports from
github.com/Snider/Borg to forge.lthn.ai/Snider/Borg. Also updates
Enchantrix dependency path to forge.lthn.ai/Snider/Enchantrix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:39:18 +00:00
..
src feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
tests chore: migrate module path from github.com to forge.lthn.ai 2026-02-22 21:39:18 +00:00
composer.json feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
README.md feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00

Borg STMF for PHP

Sovereign Form Encryption - Decrypt STMF payloads using X25519 + ChaCha20-Poly1305.

Requirements

  • PHP 7.2 or later
  • ext-sodium (included in PHP 7.2+)
  • ext-json

Installation

composer require borg/stmf

Quick Start

<?php

use Borg\STMF\STMF;

// Initialize with your private key
$stmf = new STMF($privateKeyBase64);

// Decrypt the form payload from POST
$formData = $stmf->decrypt($_POST['_stmf_payload']);

// Access form fields
$email = $formData->get('email');
$password = $formData->get('password');

// Access all fields as array
$allFields = $formData->toArray();

// Access metadata
$origin = $formData->getOrigin();
$timestamp = $formData->getTimestamp();

Laravel Integration

// In a controller
public function handleForm(Request $request)
{
    $stmf = new STMF(config('app.stmf_private_key'));
    $formData = $stmf->decrypt($request->input('_stmf_payload'));

    // Use decrypted data
    $user = User::create([
        'email' => $formData->get('email'),
        'password' => Hash::make($formData->get('password')),
    ]);
}

Key Generation

Generate a keypair in Go:

import "github.com/Snider/Borg/pkg/stmf"

kp, _ := stmf.GenerateKeyPair()
fmt.Println("Public key:", kp.PublicKeyBase64())  // Put in HTML
fmt.Println("Private key:", kp.PrivateKeyBase64()) // Put in PHP config

Or generate in PHP (for testing):

use Borg\STMF\KeyPair;

$keypair = KeyPair::generate();
echo "Public: " . $keypair->getPublicKeyBase64() . "\n";
echo "Private: " . $keypair->getPrivateKeyBase64() . "\n";

API Reference

STMF

// Constructor
$stmf = new STMF(string $privateKeyBase64);

// Decrypt a base64-encoded payload
$formData = $stmf->decrypt(string $payloadBase64): FormData;

// Decrypt raw bytes
$formData = $stmf->decryptRaw(string $payload): FormData;

// Validate without decrypting
$isValid = $stmf->validate(string $payloadBase64): bool;

// Get payload info without decrypting
$info = $stmf->getInfo(string $payloadBase64): array;

FormData

// Get a single field value
$value = $formData->get(string $name): ?string;

// Get a field object (includes type, filename, mime)
$field = $formData->getField(string $name): ?FormField;

// Get all values for a field name
$values = $formData->getAll(string $name): array;

// Check if field exists
$exists = $formData->has(string $name): bool;

// Convert to associative array
$array = $formData->toArray(): array;

// Get all fields
$fields = $formData->fields(): array;

// Get metadata
$meta = $formData->getMetadata(): array;
$origin = $formData->getOrigin(): ?string;
$timestamp = $formData->getTimestamp(): ?int;

FormField

$field->name;     // Field name
$field->value;    // Field value
$field->type;     // Field type (text, password, file, etc.)
$field->filename; // Filename for file uploads
$field->mimeType; // MIME type for file uploads

$field->isFile(): bool;           // Check if this is a file field
$field->getFileContent(): ?string; // Get decoded file content

Security

  • Hybrid encryption: X25519 ECDH key exchange + ChaCha20-Poly1305
  • Forward secrecy: Each form submission uses a new ephemeral keypair
  • Authenticated encryption: Decryption fails if data was tampered with
  • Libsodium: Uses PHP's built-in sodium extension