From 9efd8dae2a7abe15c4ef9383b7be17ef49f036de Mon Sep 17 00:00:00 2001 From: Ivan Petak Date: Thu, 14 Mar 2024 21:06:40 +0100 Subject: [PATCH] Add support for AES cipher --- includes/core/class-kekspay-connector.php | 9 ++-- includes/utilities/class-kekspay-data.php | 60 ++++++++++++++++++----- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/includes/core/class-kekspay-connector.php b/includes/core/class-kekspay-connector.php index 119d731..d1e02cc 100644 --- a/includes/core/class-kekspay-connector.php +++ b/includes/core/class-kekspay-connector.php @@ -46,8 +46,6 @@ private function get_default_args( $body ) { /** * Trigger refund for given order and amount. - * If failed to refund, method calls itself with $use_deprecated_id set to true - * to try to refund order with old version of transaction ID. * * @param WC_Order $order * @param float $amount @@ -71,13 +69,18 @@ public function refund( $order, $amount ) { $timestamp = time(); + $hash = Kekspay_Data::get_hash( $order, $refund_amount, $timestamp ); + if ( ! $hash ) { + return false; + } + $body = array( 'bill_id' => Kekspay_Data::get_bill_id_by_order_id( $order->get_id() ), 'tid' => Kekspay_Data::get_settings( 'webshop-tid', true ), 'cid' => Kekspay_Data::get_settings( 'webshop-cid', true ), 'amount' => $refund_amount, 'epochtime' => $timestamp, - 'hash' => Kekspay_Data::get_hash( $order, $refund_amount, $timestamp ), + 'hash' => $hash, 'currency' => $refund_currency, ); diff --git a/includes/utilities/class-kekspay-data.php b/includes/utilities/class-kekspay-data.php index 0de4a33..47982cb 100644 --- a/includes/utilities/class-kekspay-data.php +++ b/includes/utilities/class-kekspay-data.php @@ -282,27 +282,61 @@ public static function get_sell_data( $order, $callbacks = false ) { return $sell; } + /** + * Detects the cipher to use based on the key stored. + * Currently supporting: - 3DES + * - AES + * + * @param string $key Secret key used for hashing. + * + * @return string + */ + public static function get_cipher( $key ) { + $key_size = strlen( $key ); + + if ( ctype_xdigit( $key ) ) { + if ( $key_size === 24 ) { + return 'des-ede3-cbc'; + } else { + throw new Exception( 'Secret key must be 24 bytes.' ); + } + } else { + if ( in_array( $key_size, array( 16, 24, 32 ), true ) ) { + return 'aes-' . ( $key_size * 8 ) . '-cbc'; + } else { + throw new Exception( 'Secret key must be 16, 24 or 32 bytes.' ); + } + } + } + /** * Return hash created from the provided data and secret. * - * @param string $order Order from which to extract data for hash. + * @param object $order Order from which to extract data for hash. * @param string $timestamp Timestamp for creating hash. * * @return string */ public static function get_hash( $order, $amount, $timestamp ) { - // Get hashing key from the plugins settings. - $key = self::get_settings( 'webshop-secret-key', true ); - // Concat epochtime + webshop tid + order amount + bill_id for payload. - $payload = $timestamp . self::get_settings( 'webshop-tid', true ) . $amount . self::get_bill_id_by_order_id( $order->get_id() ); - // Extract bytes from md5 hex hash. - $payload_checksum = pack( 'H*', md5( $payload ) ); - // Create 8 byte binary initialization vector. - $iv = str_repeat( pack( 'c', 0 ), 8 ); - // Encrypt data using 3DES CBC algorithm and convert it to hex. - $hash = bin2hex( openssl_encrypt( $payload_checksum, 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, $iv ) ); - - return strtoupper( $hash ); + try { + // Get hashing key from the plugins settings. + $key = self::get_settings( 'webshop-secret-key', true ); + // Define the cipher used for hashing. + $cipher = self::get_cipher( $key ); + // Concat epochtime + webshop tid + order amount + bill_id for payload. + $payload = $timestamp . self::get_settings( 'webshop-tid', true ) . $amount . self::get_bill_id_by_order_id( $order->get_id() ); + // Extract bytes from md5 hex hash. + $payload_checksum = pack( 'H*', md5( $payload ) ); + // Create 8 or 16 (depending on cipher) byte binary initialization vector. + $iv = str_repeat( pack( 'c', 0 ), false !== strpos( $cipher, 'aes' ) ? 16 : 8 ); + // Encrypt data using 3DES CBC algorithm and convert it to hex. + $hash = bin2hex( openssl_encrypt( $payload_checksum, $cipher, $key, OPENSSL_RAW_DATA, $iv ) ); + + return strtoupper( $hash ); + } catch ( Exception $e ) { + Kekspay_Logger::log( 'Error while generating hash:' . $e->getMessage(), 'error' ); + } + } }