PHP SDK Guide
Installation
bash
composer require guzzlehttp/guzzle
# PHP 8.0+ with OpenSSL extension (for RSA encryption)Basic Usage
php
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$apiBaseUrl = 'https://keyclaim.org/api';
$apiKey = 'kc_your_api_key_here';
// Step 1: Create a challenge
function createChallenge($apiKey, $apiBaseUrl) {
$client = new Client();
$response = $client->post("$apiBaseUrl/challenge/create", [
'json' => [
'key' => $apiKey,
'ttl' => 30
]
]);
$data = json_decode($response->getBody(), true);
return $data['challenge'];
}
// Step 2: Generate response from challenge
// Option A: HMAC-based response (recommended for backend)
function generateResponseHMAC($challenge, $secret) {
return hash_hmac('sha256', $challenge, $secret);
}
// Option B: RSA Encryption-based (for frontend with private key)
function decryptChallenge($encryptedChallenge, $privateKeyPem) {
$encrypted = base64_decode($encryptedChallenge);
$decrypted = '';
if (!openssl_private_decrypt(
$encrypted,
$decrypted,
$privateKeyPem,
OPENSSL_PKCS1_OAEP_PADDING
)) {
throw new Exception('Failed to decrypt challenge');
}
return $decrypted;
}
// Step 3: Validate the response
function validateChallenge($apiKey, $apiBaseUrl, $challenge, $response, $decryptedChallenge = null) {
$client = new Client();
$payload = [
'key' => $apiKey,
'challenge' => $challenge,
'response' => $response
];
if ($decryptedChallenge !== null) {
$payload['decryptedChallenge'] = $decryptedChallenge;
}
$response = $client->post("$apiBaseUrl/challenge/validate", [
'json' => $payload
]);
return json_decode($response->getBody(), true);
}
// Complete example (HMAC)
try {
// Create challenge
$challenge = createChallenge($apiKey, $apiBaseUrl);
echo "Challenge: $challenge\n";
// Generate response
$secret = $apiKey;
$response = generateResponseHMAC($challenge, $secret);
echo "Response: $response\n";
// Validate
$result = validateChallenge($apiKey, $apiBaseUrl, $challenge, $response);
print_r($result);
if ($result['valid']) {
echo "✓ Challenge validated successfully!\n";
if (isset($result['signature'])) {
echo "Signature: {$result['signature']}\n";
}
} else {
echo "✗ Validation failed\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}Complete SDK Class
php
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class KeyClaimClient {
private $apiKey;
private $baseUrl;
private $client;
private $privateKeyPem;
public function __construct($apiKey, $baseUrl = 'https://keyclaim.org/api', $privateKeyPem = null) {
$this->apiKey = $apiKey;
$this->baseUrl = $baseUrl;
$this->client = new Client();
$this->privateKeyPem = $privateKeyPem;
}
public function createChallenge($ttl = 30) {
try {
$response = $this->client->post("$this->baseUrl/challenge/create", [
'headers' => [
'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json',
],
'json' => [
'ttl' => $ttl
]
]);
return json_decode($response->getBody(), true);
} catch (RequestException $e) {
throw new Exception('Failed to create challenge: ' . $e->getMessage());
}
}
public function generateResponseHMAC($challenge) {
return hash_hmac('sha256', $challenge, $this->apiKey);
}
public function decryptChallenge($encryptedChallenge) {
if (!$this->privateKeyPem) {
throw new Exception('Private key not provided');
}
$encrypted = base64_decode($encryptedChallenge);
$decrypted = '';
if (!openssl_private_decrypt(
$encrypted,
$decrypted,
$this->privateKeyPem,
OPENSSL_PKCS1_OAEP_PADDING
)) {
throw new Exception('Failed to decrypt challenge');
}
return $decrypted;
}
public function validate($challenge, $response, $decryptedChallenge = null) {
try {
$payload = [
'key' => $this->apiKey,
'challenge' => $challenge,
'response' => $response
];
if ($decryptedChallenge !== null) {
$payload['decryptedChallenge'] = $decryptedChallenge;
}
$response = $this->client->post("$this->baseUrl/challenge/validate", [
'json' => $payload
]);
return json_decode($response->getBody(), true);
} catch (RequestException $e) {
throw new Exception('Failed to validate: ' . $e->getMessage());
}
}
public function validateChallenge($challenge, $method = 'hmac') {
if ($method === 'hmac') {
$response = $this->generateResponseHMAC($challenge);
return $this->validate($challenge, $response);
} elseif ($method === 'rsa' && $this->privateKeyPem) {
$decrypted = $this->decryptChallenge($challenge);
return $this->validate($challenge, $decrypted, $decrypted);
} else {
throw new Exception("Unknown method: $method");
}
}
}
// Usage
$client = new KeyClaimClient('kc_your_api_key', 'https://keyclaim.org/api');
// HMAC method
$result = $client->createChallenge();
$challenge = $result['challenge'];
$validation = $client->validateChallenge($challenge, 'hmac');
print_r($validation);
// RSA method (with private key)
// If API key has a key pair assigned, challenge will be automatically encrypted
// $privateKey = file_get_contents('private_key.pem');
// $clientRSA = new KeyClaimClient('kc_your_api_key', 'https://keyclaim.org/api', $privateKey);
// $result = $clientRSA->createChallenge(30);
// $challenge = $result['challenge'];
// $validation = $clientRSA->validateChallenge($challenge, 'rsa');
// print_r($validation);RSA Key Pair Generation
php
<?php
function generateRSAKeyPair($keySize = 2048) {
$config = [
"digest_alg" => "sha256",
"private_key_bits" => $keySize,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
// Generate private key
$resource = openssl_pkey_new($config);
if (!$resource) {
throw new Exception('Failed to generate key pair');
}
// Export private key
openssl_pkey_export($resource, $privateKeyPem);
// Get public key
$publicKeyDetails = openssl_pkey_get_details($resource);
$publicKeyPem = $publicKeyDetails['key'];
return [
'private_key' => $privateKeyPem,
'public_key' => $publicKeyPem
];
}
// Generate and save
$keyPair = generateRSAKeyPair(2048);
file_put_contents('private_key.pem', $keyPair['private_key']);
file_put_contents('public_key.pem', $keyPair['public_key']);
echo "Key pair generated!\n";
echo "Private key saved to: private_key.pem\n";
echo "Public key saved to: public_key.pem\n";
echo "\n⚠️ Keep your private key secure!\n";Laravel Integration
php
<?php
// app/Services/KeyClaimService.php
namespace App\Services;
use GuzzleHttp\Client;
class KeyClaimService {
private $client;
private $apiKey;
private $baseUrl;
public function __construct() {
$this->client = new Client();
$this->apiKey = config('services.keyclaim.api_key');
$this->baseUrl = config('services.keyclaim.base_url', 'https://keyclaim.org/api');
}
public function createChallenge($ttl = 30) {
$response = $this->client->post("$this->baseUrl/challenge/create", [
'json' => [
'key' => $this->apiKey,
'ttl' => $ttl
]
]);
return json_decode($response->getBody(), true);
}
public function validate($challenge, $response) {
$response = $this->client->post("$this->baseUrl/challenge/validate", [
'json' => [
'key' => $this->apiKey,
'challenge' => $challenge,
'response' => $response
]
]);
return json_decode($response->getBody(), true);
}
}
// config/services.php
return [
'keyclaim' => [
'api_key' => env('KEYCLAIM_API_KEY'),
'base_url' => env('KEYCLAIM_BASE_URL', 'https://keyclaim.org/api'),
],
];
// Usage in Controller
use App\Services\KeyClaimService;
$keyClaim = new KeyClaimService();
$challenge = $keyClaim->createChallenge();Explore Other Documentation
Choose your preferred programming language

Node.js Documentation
JavaScript/TypeScript integration guide
View Guide→

Python Documentation
Python 3.7+ integration guide
View Guide→

Java Documentation
Java 8+ integration guide
View Guide→

Kotlin Documentation
Kotlin/JVM integration guide
View Guide→
C# Documentation
.NET/C# integration guide
View Guide→

Go Documentation
Go 1.18+ integration guide
View Guide→
