ifabula/sevola-sdk-php

PHP SDK for Sevola encryption service - Format-preserving and AES-GCM encryption

Maintainers

Package info

gitlab.com/kasfi.tamiya/sevola-sdk-php

Issues

pkg:composer/ifabula/sevola-sdk-php

Statistics

Installs: 6

Dependents: 1

Suggesters: 0

Stars: 0

v1.0.1 2026-04-17 11:20 UTC

This package is not auto-updated.

Last update: 2026-04-17 04:32:09 UTC


README

PHP SDK for format-preserving and AES-GCM encryption via Sevola service.

Features

  • AES "transit" and "rest" encryption for arbitrary payloads
  • FF1 format-preserving encryption using Ubiq Security library
  • Key retrieval from Sevola API
  • PHP 8.2+ compatibility
  • Thread-safe operations
  • Configurable timeout and base URL
  • Comprehensive error handling

Installation

Via Composer

composer require ifabula/sevola-sdk-php

Or add to your composer.json:

{
    "require": {
        "ifabula/sevola-sdk-php": "^1.0.0"
    },
    "repositories": [
        {
            "type": "path",
            "url": "./sevola-sdk-php"
        }
    ]
}

Then run:

composer install

Quick Start

1. Basic Usage

<?php

require 'vendor/autoload.php';

use Ifabula\Sevola\EncryptClient;

// Create client with API key
$client = EncryptClient::new('your-api-key');

// Encrypt data at rest
$plaintext = 'Hello, World!';
$encrypted = $client->encryptData($plaintext);

// Decrypt data
$decrypted = $client->decryptData($encrypted);

echo "Original: $plaintext\n";
echo "Encrypted: $encrypted\n";
echo "Decrypted: $decrypted\n";

2. Advanced Configuration

<?php

require 'vendor/autoload.php';

use Ifabula\Sevola\EncryptClient;
use Ifabula\Sevola\EncryptClientOptions;

// Create client with custom options
$options = new EncryptClientOptions(
    apiKey: 'your-api-key',
    baseURL: 'https://your-sevola-server.com',
    timeout: 60
);
$client = EncryptClient::newWithOptions($options);

// Use transit encryption for data in motion
$encrypted = $client->encryptTransit('sensitive data');
$decrypted = $client->decryptTransit($encrypted);

echo "Transit encrypted: $encrypted\n";
echo "Transit decrypted: $decrypted\n";

3. FF1 Format-Preserving Encryption

<?php

require 'vendor/autoload.php';

use Ifabula\Sevola\EncryptClient;

$client = EncryptClient::new('your-api-key');

// Encrypt with FF1
$requests = [
    [
        'template' => 'numeric',
        'data' => '1234-5678-9012'
    ]
];

$results = $client->encryptDataFF1($requests);
foreach ($results as $result) {
    echo "Status: {$result['status']}\n";
    echo "Value: {$result['value']}\n";
}

// Decrypt with FF1
$decryptRequests = [
    [
        'template' => 'numeric',
        'value' => $results[0]['value']
    ]
];

$decryptResults = $client->decryptDataFF1($decryptRequests);
foreach ($decryptResults as $result) {
    echo "Status: {$result['status']}\n";
    echo "Data: {$result['data']}\n";
}

API Reference

Types

EncryptClientOptions

class EncryptClientOptions {
    public string $apiKey;        // Required: API key for authentication
    public string $baseURL;       // Optional: Base URL (default: "http://localhost:8082")
    public int $timeout;          // Optional: Timeout in seconds (default: 30)
    public bool $logger;          // Optional: Enable debug logging (default: false)
    public bool $enableCaching;   // Optional: Enable key caching for non-dynamic keys (default: false)
    public int $cacheTTL;         // Optional: Cache TTL in seconds for non-dynamic keys (default: 300)
}

Caching behaviour:

  • Dynamic keys (used by encryptTransitDynamic / decryptTransitDynamic) are always cached for 1 minute regardless of enableCaching.
  • Regular REST/transit keys are only cached when enableCaching: true, using cacheTTL (default 5 minutes).
  • Call clearCache() to evict all cached keys, or getCacheSize() to inspect the cache.

Functions

EncryptClient::new(string $apiKey): EncryptClient

Creates a new client with default settings.

EncryptClient::newWithOptions(EncryptClientOptions $options): EncryptClient

Creates a new client with custom configuration.

Methods

encryptData(string $plaintext): string

Encrypts data using "rest" key type (for data at rest).

decryptData(string $cipherText): string

Decrypts data using "rest" key type.

encryptTransit(string $plaintext): string

Encrypts data using "transit" key type (for data in transit).

decryptTransit(string $cipherText): string

Decrypts data using "transit" key type.

encryptTransitDynamic(string $plaintext): string

Encrypts data using dynamic transit keys.

decryptTransitDynamic(string $cipherText): string

Decrypts data using dynamic transit keys.

encryptDataFF1(array $requests): array

Encrypts data using FF1 format-preserving encryption. Each request should have:

  • template: "numeric" or "alfanum"
  • data: The data to encrypt

Returns an array of results with status and value keys.

decryptDataFF1(array $requests): array

Decrypts data using FF1 format-preserving encryption. Each request should have:

  • template: "numeric" or "alfanum"
  • value: The encrypted value to decrypt

Returns an array of results with status and data keys.

clearCache(): void

Removes all cached encryption keys, forcing the next operation to fetch fresh keys from the server.

getCacheSize(): int

Returns the number of currently cached keys (useful for debugging/monitoring).

Short-String Handling (Magic Markers)

FF1 requires a minimum input length (4 chars for alfanum, 6 digits for numeric). The SDK transparently handles shorter inputs using a magic-marker scheme so callers never need to worry about length constraints.

How it works

Encryption: before passing the cleaned string to FF1, encryptDataFF1 calls escapeAndWrap:

  • If the input contains the base marker → append the escape marker (collision prevention).
  • If the input is shorter than the minimum → append the padding marker, the original length as a single digit, then random chars to reach the minimum.
  • Otherwise the input is passed through unchanged.

Decryption: after FF1 decryption and special-char restoration, decryptDataFF1 calls unwrapAndUnescape:

  • If the result ends with the escape marker → strip it.
  • If the result contains the padding marker → read the length digit and return the original prefix.
  • Otherwise the result is returned unchanged.

Marker reference

TemplateBase markerPadding markerEscape markerMin length
alfanumZ9YZ9YXZ9YZ4
numeric907890780907816

Testing

Run the test suite:

# Run all tests
composer test

# Run tests with coverage
composer test -- --coverage

Building

Build the module:

# Install dependencies
composer install

# Run tests
composer test

Publishing

1. Tag a Release

# Tag the release
git tag v1.0.0
git push origin v1.0.0

2. Composer Package Repository

The package can be installed via Composer once published to a repository:

# Users can install with:
composer require ifabula/sevola-sdk-php

Dependencies

  • PHP 8.2+ - Required for the library
  • guzzlehttp/guzzle - HTTP client for API requests
  • ubiqsecurity/ubiq-php - FF1 format-preserving encryption library
  • ext-openssl - OpenSSL extension for cryptographic operations
  • ext-json - JSON extension for API responses

Examples

See the examples/ directory for more usage examples.

License

MIT © PT Ifabula Digital Kreasi

Support

For issues and questions:

  • Create an issue on GitLab
  • Email: kasfi.tamiya@ifabula.com