From 0e190c085a5ec0db5df72fc585bbb40c45ce2c1e Mon Sep 17 00:00:00 2001 From: netkas Date: Mon, 3 Feb 2025 13:59:11 -0500 Subject: [PATCH] Added method signTimedMessage() and verifyTimedMessage() for verifying messages based on signed timestamps --- src/Socialbox/Classes/Cryptography.php | 75 +++++++++++++++++++ .../Status/SignatureVerificationStatus.php | 21 ++++++ src/Socialbox/Socialbox.php | 51 +++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/Socialbox/Enums/Status/SignatureVerificationStatus.php diff --git a/src/Socialbox/Classes/Cryptography.php b/src/Socialbox/Classes/Cryptography.php index b7b6e2c..9d83e9d 100644 --- a/src/Socialbox/Classes/Cryptography.php +++ b/src/Socialbox/Classes/Cryptography.php @@ -347,6 +347,43 @@ } } + /** + * Signs a message using the provided private key and a timestamp. + * + * @param string $message The message to be signed. + * @param string $privateKey The base64-encoded private key used for signing. + * @param int $timestamp The timestamp to be included in the signed message. + * @param bool $hash True to hash the message before signing, false to use the message directly. + * @return string The base64-encoded digital signature. + * @throws CryptographyException If the message or private key is invalid, or if signing fails. + */ + public static function signTimedMessage(string $message, string $privateKey, int $timestamp, bool $hash=true): string + { + if (empty($message)) + { + throw new CryptographyException("Empty message provided"); + } + + if($timestamp <= 0) + { + throw new CryptographyException("Invalid timestamp provided"); + } + + if($hash) + { + $message = hash('sha512', $message); + } + else + { + if(!self::validateSha512($message)) + { + throw new CryptographyException("Invalid SHA-512 hash provided"); + } + } + + return self::signMessage(sprintf("digest:%s;timestamp:%d", $message, $timestamp), $privateKey); + } + /** * Verifies the validity of a given signature for a message using the provided public key. * @@ -405,6 +442,44 @@ } } + /** + * Verifies the validity of a given signature for a message using the provided public key and timestamp. + * + * @param string $message The original message that was signed. + * @param string $signature The base64-encoded signature to be verified. + * @param string $publicKey The base64-encoded public key used to verify the signature. + * @param int $timestamp The timestamp to be included in the signed message. + * @param bool $hash True to hash the message before verification, false to use the message directly. + * @return bool True if the signature is valid; false otherwise. + * @throws CryptographyException If any parameter is empty, if the public key or signature is invalid, or if the verification process fails. + */ + public static function verifyTimedMessage(string $message, string $signature, string $publicKey, int $timestamp, bool $hash=true): bool + { + if (empty($message) || empty($signature) || empty($publicKey)) + { + throw new CryptographyException("Empty parameter(s) provided"); + } + + if($timestamp <= 0) + { + throw new CryptographyException("Invalid timestamp provided"); + } + + if($hash) + { + $message = hash('sha512', $message); + } + else + { + if(!self::validateSha512($message)) + { + throw new CryptographyException("Invalid SHA-512 hash provided"); + } + } + + return self::verifyMessage(sprintf("digest:%s;timestamp:%d", $message, $timestamp), $signature, $publicKey); + } + /** * Determines if the provided algorithm is supported. * diff --git a/src/Socialbox/Enums/Status/SignatureVerificationStatus.php b/src/Socialbox/Enums/Status/SignatureVerificationStatus.php new file mode 100644 index 0000000..17f4055 --- /dev/null +++ b/src/Socialbox/Enums/Status/SignatureVerificationStatus.php @@ -0,0 +1,21 @@ +getPublicKey(), false)) + { + return SignatureVerificationStatus::INVALID; + } + } + catch (CryptographyException) + { + return SignatureVerificationStatus::INVALID; + } + } + /** * Resolves a peer signature key based on the given peer address or string identifier. *