Fix critical signature compatibility with client library (v0.5.5)

CRITICAL: Key derivation now uses native hash_hkdf() for RFC 5869
compliance. Previous custom implementation was incompatible with
the magdev/wc-licensed-product-client library.

Changes:
- ResponseSigner::deriveCustomerSecret() now uses hash_hkdf()
- Added missing domain validation to /activate endpoint
- Customer secrets will change after upgrade (breaking change)

The signature algorithm now matches the client's ResponseSignature::deriveKey():
- IKM: server_secret
- Length: 32 bytes
- Info: license_key

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-26 17:06:18 +01:00
parent ae49b262fa
commit 0b58de193e
5 changed files with 64 additions and 5 deletions

View File

@@ -157,16 +157,23 @@ final class ResponseSigner
* to verify signed API responses. Each customer gets their own secret
* derived from their license key.
*
* Uses RFC 5869 HKDF via PHP's native hash_hkdf() function.
* Parameters match the client library (SecureLicenseClient):
* - IKM (input keying material): server_secret
* - Length: 32 bytes (256 bits for SHA-256)
* - Info: license_key (context-specific info)
*
* @param string $licenseKey The customer's license key
* @param string $serverSecret The server's master secret
* @return string The derived secret (64 hex characters)
*/
public static function deriveCustomerSecret(string $licenseKey, string $serverSecret): string
{
// HKDF-like key derivation
$prk = hash_hmac('sha256', $licenseKey, $serverSecret, true);
// RFC 5869 HKDF using PHP's native implementation
// Must match client's ResponseSignature::deriveKey() exactly
$binaryKey = hash_hkdf('sha256', $serverSecret, 32, $licenseKey);
return hash_hmac('sha256', $prk . "\x01", $serverSecret);
return bin2hex($binaryKey);
}
/**