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: 31

Dependents: 1

Suggesters: 0

Stars: 0

v1.1.0 2026-05-28 14:45 UTC

This package is not auto-updated.

Last update: 2026-06-25 08:08:15 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 for data at rest
  • Key retrieval from Sevola API
  • PHP 7.3+ 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";

Compatibility note

Namespace resmi untuk raw SDK adalah:

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

Versi ini juga menyediakan alias kompatibilitas untuk contoh awal yang memakai Ifabula\SevolaInterceptor\EncryptClient. Jadi kode lama seperti ini tetap akan diarahkan ke client SDK:

use Ifabula\SevolaInterceptor\EncryptClient;

$sdk = new EncryptClient([
    'apiKey' => 'your-api-key',
    'baseUrl' => 'https://your-sevola-server.com',
    'timeout' => 60,
]);

Untuk implementasi baru, tetap gunakan namespace resmi Ifabula\Sevola.

2. Advanced Configuration

<?php

require 'vendor/autoload.php';

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

// Create client with custom options
$options = new EncryptClientOptions(
    'your-api-key',
    'https://your-sevola-server.com',
    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";
}

Interop Test With Python SDK

Run this from the PHP SDK repository to validate FF1 at-rest compatibility with the Python SDK:

cd /Users/anggitsy/Documents/myproject/ENCRYPT/sevola-sdk-php
python3 tests/interop/test_ff1_interop_with_python.py --use-docker

To validate specifically with PHP 7.3, build the local test image first:

docker build -t sevola-php73-test -f docker/php73/Dockerfile .
python3 tests/interop/test_ff1_interop_with_python.py --use-docker --php-docker-image sevola-php73-test

The test validates both directions:

  • Python encrypts numeric and alphanumeric payloads, PHP decrypts them.
  • PHP encrypts the same payloads, Python decrypts them.

If PHP and Composer are installed locally, you can run without Docker after composer install:

python3 tests/interop/test_ff1_interop_with_python.py

API Reference

Types

EncryptClientOptions

class EncryptClientOptions {
    public $apiKey;        // Required: API key for authentication
    public $baseURL;       // Optional: Base URL (default: "http://localhost:8082")
    public $timeout;       // Optional: Timeout in seconds (default: 30)
    public $logger;        // Optional: Enable debug logging (default: false)
    public $enableCaching; // Optional: Enable key caching for non-dynamic keys (default: false)
    public $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", "alfanum", or "alphanumeric"
  • 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", "alfanum", or "alphanumeric"
  • 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 7.3+ - Required for the library
  • guzzlehttp/guzzle - HTTP client for API requests
  • phpseclib/phpseclib - Big integer and AES primitives for FF1
  • ext-openssl - OpenSSL extension for cryptographic operations
  • ext-json - JSON extension for API responses
  • ext-mbstring - Multibyte string handling for FF1 payloads

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