t2pcorp / libcrypto
A PHP library for cryptographic operations with KMS integration, Caching(local,redis) and Secret manager.
Requires
- php: >=7.4 || >=8.0
- ext-json: *
- ext-openssl: *
- ext-sodium: *
- aws/aws-sdk-php: ^3.337
- predis/predis: ^v2.4.0
README
PHP implementation of the LibCrypto library, converted from the original Golang version. This library provides secure encryption/decryption functionality with support for multiple key versions, caching, and AWS integration.
Features
- AES-256-GCM Encryption: Secure encryption using industry-standard algorithms
- Key Versioning: Support for multiple key versions with automatic rotation
- Multi-level Caching: Local and Redis caching for improved performance
- AWS Integration: Support for AWS Secrets Manager and KMS
- Mock Support: Complete mock implementations for testing and development
- Thread-Safe: Singleton pattern ensures thread safety
Directory Structure
PHP/
├── Cache/
│ ├── LocalCache/ # In-memory caching implementation
│ └── RedisCache/ # Redis-based caching implementation
├── Encryption/
│ └── LibKMS/ # AWS KMS encryption services
├── LibAWS/ # AWS configuration and utilities
├── LibConfig/ # Configuration management
│ └── MockConfig/ # Mock configuration for testing
├── Stores/
│ ├── SecretManager/ # AWS Secrets Manager integration
│ └── MockSecretManager/ # Mock secret store for testing
├── Types/ # Interface definitions and data structures
├── Utils/ # Utility functions and helpers
├── tests/ # Comprehensive test suite
├── examples.php # Usage examples
├── LibCrypto.php # Main library entry point
└── run.sh # Test runner script
Installation
Prerequisites
- PHP 8.0 or higher
- Required PHP extensions:
openssl
json
mbstring
- Composer (for dependency management)
Dependencies
Install required dependencies using Composer:
composer install
AWS Dependencies (Optional)
For AWS integration, you'll need:
- AWS SDK for PHP
- Predis (for Redis support)
These are automatically installed via Composer.
Quick Start
Basic Usage with Mock Store
<?php
require_once 'vendor/autoload.php';
use LibCrypto\CryptoManager;
use LibCrypto\Types\CryptoConfig;
use LibCrypto\Stores\MockSecretManager\KeyStore as MockKeyStore;
// Create configuration
$config = new CryptoConfig([
'LIBC_SM_NAME' => 'T2P-LIBC-DEK-poc',
'LIBC_SM_REGION' => 'ap-southeat-7'
]);
// Use mock store for testing
$mockStore = new MockKeyStore($config);
// Get CryptoManager instance
$result = CryptoManager::getCryptoManager($config, $mockStore);
if ($result[1] !== null) {
throw new Exception('Failed to initialize: ' . $result[1]);
}
$cryptoManager = $result[0];
// Encrypt data
$plaintext = "Hello, World!";
$encryptResult = $cryptoManager->encrypt($plaintext);
if ($encryptResult[1] !== null) {
throw new Exception('Encryption failed: ' . $encryptResult[1]);
}
$encrypted = $encryptResult[0];
echo "Encrypted: " . $encrypted . "\n";
// Decrypt data
$decryptResult = $cryptoManager->decrypt($encrypted);
if ($decryptResult[1] !== null) {
throw new Exception('Decryption failed: ' . $decryptResult[1]);
}
$decrypted = $decryptResult[0];
echo "Decrypted: " . $decrypted . "\n";
Usage with AWS Integration
<?php
use LibCrypto\Stores\SecretManager\KeyStore as RealKeyStore;
// Configure with AWS credentials
$config = new CryptoConfig([
'LIBC_SM_NAME' => 'your-secret-name',
'LIBC_SM_ID' => 'your-aws-access-key',
'LIBC_SM_SECRET' => 'your-aws-secret-key',
'LIBC_SM_REGION' => 'ap-southeat-7',
'LIBC_CACHE_REDISHOST' => 'your-redis-host',
'LIBC_CACHE_REDISPORT' => '6379'
]);
$realStore = new RealKeyStore($config);
$result = CryptoManager::getCryptoManager($config, $realStore);
// ... use as above
Configuration
Environment Variables
The library supports configuration via environment variables:
LIBC_SM_NAME
: AWS Secrets Manager secret nameLIBC_SM_ID
: AWS Access Key IDLIBC_SM_SECRET
: AWS Secret Access KeyLIBC_SM_ROLE
: AWS IAM Role ARN (optional)LIBC_SM_REGION
: AWS RegionLIBC_CACHE_REDISHOST
: Redis hostLIBC_CACHE_REDISPORT
: Redis portLIBC_CACHE_REDISPASS
: Redis passwordLIBC_CACHE_REDISDB
: Redis database numberLIBC_CACHE_REDISTLS
: Enable Redis TLS (true/false)
Configuration Object
$config = new CryptoConfig([
'LIBC_SM_NAME' => 'my-secret',
'LIBC_SM_REGION' => 'us-west-2',
// ... other options
]);
API Reference
CryptoManager
Main class for encryption/decryption operations.
Methods
getCryptoManager(CryptoConfig $config, StoreInterface $store = null, ConfigInterface $libConfig = null): array
- Returns
[CryptoManager instance, error]
- Singleton pattern - returns the same instance across calls
- Returns
encrypt(string $plaintext): array
- Returns
[encrypted_string, error]
- Encrypts plaintext using the active key
- Returns
decrypt(string $encrypted): array
- Returns
[decrypted_string, error]
- Decrypts encrypted data
- Returns
getCipherMeta(string $encrypted): array
- Returns
[CipherMeta object, error]
- Gets metadata about encrypted data
- Returns
clearCache(): ?string
- Returns error message or null
- Clears all cached keys and forces refresh
CipherMeta
Contains metadata about encrypted data:
class CipherMeta {
public string $version; // Key version used
public string $algorithm; // Encryption algorithm
public bool $isSupport; // Whether format is supported
}
Testing
Run All Tests
./run.sh
Run Specific Tests
# Basic examples
./run.sh 1
# Comprehensive tests
./run.sh 2
# Performance benchmark
./run.sh 3
# Installation check
./run.sh 4
Manual Testing
# Run examples
php examples.php
# Run test suite
php tests/LibCryptoTest.php
Performance
The library includes performance benchmarking:
use LibCrypto\Tests\PerformanceTest;
$perfTest = new PerformanceTest($cryptoManager);
$perfTest->benchmarkEncryption(1000); // Run 1000 cycles
Typical performance on modern hardware:
- Encryption: ~2-5ms per operation
- Decryption: ~2-5ms per operation
- Throughput: ~200-500 operations/second
Error Handling
The library uses a Go-style error handling pattern where methods return arrays:
[result, null]
on success[null, error_message]
on failure
$result = $cryptoManager->encrypt($data);
if ($result[1] !== null) {
// Handle error
echo "Error: " . $result[1];
} else {
// Use result
$encrypted = $result[0];
}
Caching
Local Cache
In-memory caching for single-process applications:
- Fast access
- No external dependencies
- Lost on process restart
Redis Cache
Distributed caching for multi-process/multi-server applications:
- Persistent across restarts
- Shared between processes
- Requires Redis server
Cache Timeout
- Default timeout: 20-24 hours (randomized)
- Automatic refresh on timeout
- Manual refresh via
clearCache()
Security Considerations
- Key Storage: Keys are stored securely in memory when possible
- Network Security: Use TLS for Redis connections in production
- AWS Security: Use IAM roles instead of hardcoded credentials when possible
- Memory Safety: Sensitive data is cleared from memory when possible
Differences from Go Version
Skipped Components
As requested, the following components were not converted:
limitqueue
package (timeout functionality)- Timeout/refresh queue functionality in config
PHP-Specific Adaptations
- Error Handling: Go-style
[result, error]
pattern - Interfaces: PHP interfaces instead of Go interfaces
- Memory Management: PHP garbage collection instead of manual memory management
- Concurrency: Single-threaded execution model
- Dependencies: Composer instead of Go modules
Troubleshooting
Common Issues
Missing PHP Extensions
# Install required extensions (Ubuntu/Debian) sudo apt-get install php-openssl php-json php-mbstring
AWS Credentials Not Found
- Set environment variables
- Configure AWS credentials file
- Use IAM roles on EC2
Redis Connection Failed
- Check Redis server is running
- Verify connection parameters
- Check firewall settings
Memory Issues
- Increase PHP memory limit:
ini_set('memory_limit', '512M');
- Use Redis cache for better memory management
- Increase PHP memory limit:
Debug Mode
Enable debug output:
// Add to your code for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);
Contributing
- Follow PSR-12 coding standards
- Write tests for new functionality
- Update documentation
- Run the test suite before submitting
License
This PHP conversion maintains the same license as the original Go implementation.
Support
For issues specific to the PHP conversion, please check:
- PHP version compatibility (8.0+)
- Required extensions are installed
- Dependencies are up to date
- Configuration is correct
For general LibCrypto issues, refer to the original Go documentation.
LibCrypto PHP Library
A PHP library for cryptographic operations with KMS integration, Caching (local, Redis), and Secret Manager support.
Installation
You can install this library via Composer:
composer require t2pcorp/libcrypto
Usage
Please see example.php
for basic usage.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use LibCrypto\CryptoManager;
try {
// Initialize CryptoManager (assumes environment variables are set for configuration)
[$cryptoManager, $error] = CryptoManager::getCryptoManager();
if ($error !== null) {
throw new \Exception("Failed to initialize CryptoManager: " . $error);
}
$plaintext = "Hello, secure world!";
[$encrypted, $encError] = $cryptoManager->encrypt($plaintext);
if ($encError !== null) {
throw new \Exception("Encryption failed: " . $encError);
}
echo "Encrypted: " . $encrypted . "\n";
[$decrypted, $decError] = $cryptoManager->decrypt($encrypted);
if ($decError !== null) {
throw new \Exception("Decryption failed: " . $decError);
}
echo "Decrypted: " . $decrypted . "\n";
} catch (\Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
Publishing to Packagist
To make this library publicly available via Composer, follow these steps to publish it to Packagist.org:
Ensure your code is in a public Git repository:
- Packagist tracks your Git repository (e.g., on GitHub, GitLab, Bitbucket).
- Make sure your library's code, including the
composer.json
file and thesrc/
directory, is committed and pushed to a public repository.
Sign up/Log in to Packagist:
- Go to Packagist.org.
- Sign up or log in. Using your GitHub account is often the easiest if your code is hosted there.
Submit Your Package:
- Once logged in, click the "Submit" button.
- In the "Repository URL (Git/Svn/Hg)" field, paste the public URL of your Git repository (e.g.,
https://github.com/your-username/libcrypto.git
). - Click "Check". Packagist will attempt to read your
composer.json
. - If successful and the package name
t2pcorp/libcrypto
is available, confirm the submission.
Set up Automatic Updates (Webhook):
- After submission, Packagist will show your package page. It's highly recommended to set up automatic updates.
- Packagist will provide a webhook URL.
- Go to your Git repository settings (e.g., GitHub: Settings -> Webhooks -> Add webhook).
- Paste the Payload URL from Packagist, set Content type to
application/json
, and select the "Pushes" or "Push event" trigger.
Versioning with Git Tags:
- Composer relies on Git tags for versioning. To release a new version (e.g.,
v1.0.0
):- Commit all changes:
git commit -am "Release v1.0.0"
- Create a Git tag:
git tag v1.0.0
- Push the tag:
git push origin v1.0.0
(orgit push --tags
)
- Commit all changes:
- Packagist will be notified (via webhook) and make the new version available.
- Composer relies on Git tags for versioning. To release a new version (e.g.,
🧩 4. Submit Your Package to Packagist A. On Packagist: Go to: https://packagist.org/packages/submit Paste your GitLab repository URL (e.g.): https://gitlab.com/t2plib/libcrypto.git If it’s public, it should just work.
🔄 5. Set Up Auto-Update (Recommended) To allow Packagist to auto-update when you push a new tag or commit:
Option 1: Use GitLab Webhook Go to your GitLab project → Settings → Webhooks
Add this webhook URL:
perl Copy Edit https://packagist.org/api/update-package?username=YOUR_USERNAME&apiToken=YOUR_API_TOKEN You can get apiToken from your Packagist API page
Set it to trigger on Push events.
This README.md
was generated based on the composer.json
for t2pcorp/libcrypto
.