From c75608327ac9247ea1196d4b42af07f14282f7bb Mon Sep 17 00:00:00 2001 From: May Meow <3164256+MayMeow@users.noreply.github.com> Date: Wed, 4 Jun 2025 09:50:56 +0000 Subject: [PATCH 1/6] Add legacy support for encryption and decryption methods in AESCryptoServiceProvider --- src/AESCryptoServiceProvider.php | 26 +++++++++++++++++++------- tests/AESCryptoServiceProviderTest.php | 2 ++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/AESCryptoServiceProvider.php b/src/AESCryptoServiceProvider.php index a009fa0..c4ef58e 100644 --- a/src/AESCryptoServiceProvider.php +++ b/src/AESCryptoServiceProvider.php @@ -105,7 +105,7 @@ public function generateIV(?string $cipher = null) * @param string $plainText * @return string */ - public function encrypt(string $plainText): string + public function encrypt(string $plainText, bool $legacy = false): string { $encryptedBytes = openssl_encrypt( $plainText, @@ -116,7 +116,11 @@ public function encrypt(string $plainText): string $this->tag ); - return base64_encode($this->iv . $this->tag . $encryptedBytes); + if ($legacy) { + return base64_encode($this->iv . $this->tag . $encryptedBytes); + } + + return base64_encode($this->iv . $encryptedBytes . $this->tag); } /** @@ -127,7 +131,7 @@ public function encrypt(string $plainText): string * @throws DecryptException * @throws IvGenerateException */ - public function decrypt(string $encryptedData): string + public function decrypt(string $encryptedData, bool $legacy = false): string { $c = base64_decode($encryptedData); @@ -137,10 +141,18 @@ public function decrypt(string $encryptedData): string throw new IvGenerateException(); } - $this->iv = substr($c, 0, $iv_len); - $this->tag = substr($c, $iv_len, static::DEFAULT_GCM_TAG_LENGTH); - $encryptedBytes = substr($c, $iv_len + static::DEFAULT_GCM_TAG_LENGTH); - + if ($legacy) { + // IV-TAG-EncryptedData + $this->iv = substr($c, 0, $iv_len); // from begining to iv lenght 12 bytes + $this->tag = substr($c, $iv_len, static::DEFAULT_GCM_TAG_LENGTH); // tag is 16 bytes after iv + $encryptedBytes = substr($c, $iv_len + static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are at the end + } else { + // IV-EncryptedData-TAG + $this->iv = substr($c, 0, $iv_len); // from begining to iv lenght 12 bytes + $encryptedBytes = substr($c, $iv_len, -static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are in the middle + $this->tag = substr($c, -static::DEFAULT_GCM_TAG_LENGTH); // tag is at the end + } + $decryptedText = openssl_decrypt( $encryptedBytes, $this->cipher, diff --git a/tests/AESCryptoServiceProviderTest.php b/tests/AESCryptoServiceProviderTest.php index e53535d..0d7f609 100644 --- a/tests/AESCryptoServiceProviderTest.php +++ b/tests/AESCryptoServiceProviderTest.php @@ -16,10 +16,12 @@ public function textCanBeEncryptedAndDecrypted() : void $plainText = "This is going to be encrypted!"; $encryptedText= $csp->encrypt($plainText); + $encryptedTextLegacy = $csp->encrypt($plainText, legacy: true); $csp2 = new AESCryptoServiceProvider(); $csp2->setKey($key); $this->assertEquals($plainText, $csp2->decrypt($encryptedText)); + $this->assertEquals($plainText, $csp2->decrypt($encryptedTextLegacy, legacy: true)); } } \ No newline at end of file From f75e0ff8f556b85a7c8b4b15a47b66348e1edb6c Mon Sep 17 00:00:00 2001 From: May Meow <3164256+MayMeow@users.noreply.github.com> Date: Wed, 4 Jun 2025 09:53:51 +0000 Subject: [PATCH 2/6] Fix CS Errors --- src/AESCryptoServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AESCryptoServiceProvider.php b/src/AESCryptoServiceProvider.php index c4ef58e..224f51c 100644 --- a/src/AESCryptoServiceProvider.php +++ b/src/AESCryptoServiceProvider.php @@ -152,7 +152,7 @@ public function decrypt(string $encryptedData, bool $legacy = false): string $encryptedBytes = substr($c, $iv_len, -static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are in the middle $this->tag = substr($c, -static::DEFAULT_GCM_TAG_LENGTH); // tag is at the end } - + $decryptedText = openssl_decrypt( $encryptedBytes, $this->cipher, From a6ef622a7bdfef84d62c5d0987efaf1b73c33dd6 Mon Sep 17 00:00:00 2001 From: May Meow <3164256+MayMeow@users.noreply.github.com> Date: Wed, 4 Jun 2025 09:55:23 +0000 Subject: [PATCH 3/6] Enhance documentation for encrypt and decrypt methods to clarify legacy parameter usage --- src/AESCryptoServiceProvider.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/AESCryptoServiceProvider.php b/src/AESCryptoServiceProvider.php index 224f51c..6b39e0f 100644 --- a/src/AESCryptoServiceProvider.php +++ b/src/AESCryptoServiceProvider.php @@ -103,6 +103,9 @@ public function generateIV(?string $cipher = null) * Returns encrypted text * * @param string $plainText + * @param bool $legacy + * If true, returns IV-TAG-EncryptedData format + * If false, returns IV-EncryptedData-TAG format * @return string */ public function encrypt(string $plainText, bool $legacy = false): string @@ -127,6 +130,9 @@ public function encrypt(string $plainText, bool $legacy = false): string * Decrypt given text * * @param string $encryptedData + * @param bool $legacy + * If true, expects IV-TAG-EncryptedData format + * If false, expects IV-EncryptedData-TAG format * @return string * @throws DecryptException * @throws IvGenerateException From 8c58d37a517c0cbf274b3aa6c09e4dc6e9e23f40 Mon Sep 17 00:00:00 2001 From: May Meow <3164256+MayMeow@users.noreply.github.com> Date: Wed, 4 Jun 2025 10:00:43 +0000 Subject: [PATCH 4/6] Refactor IV and TAG handling in decrypt method for clarity and consistency --- src/AESCryptoServiceProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AESCryptoServiceProvider.php b/src/AESCryptoServiceProvider.php index 6b39e0f..fb55044 100644 --- a/src/AESCryptoServiceProvider.php +++ b/src/AESCryptoServiceProvider.php @@ -147,14 +147,14 @@ public function decrypt(string $encryptedData, bool $legacy = false): string throw new IvGenerateException(); } + $this->iv = substr($c, 0, $iv_len); + if ($legacy) { // IV-TAG-EncryptedData - $this->iv = substr($c, 0, $iv_len); // from begining to iv lenght 12 bytes $this->tag = substr($c, $iv_len, static::DEFAULT_GCM_TAG_LENGTH); // tag is 16 bytes after iv $encryptedBytes = substr($c, $iv_len + static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are at the end } else { // IV-EncryptedData-TAG - $this->iv = substr($c, 0, $iv_len); // from begining to iv lenght 12 bytes $encryptedBytes = substr($c, $iv_len, -static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are in the middle $this->tag = substr($c, -static::DEFAULT_GCM_TAG_LENGTH); // tag is at the end } From e2d4af68c56db7ef1f030f27ec2b61c809bf087c Mon Sep 17 00:00:00 2001 From: May Meow <3164256+MayMeow@users.noreply.github.com> Date: Wed, 4 Jun 2025 10:49:11 +0000 Subject: [PATCH 5/6] Refactor encrypt method to use buildPayload for consistent data formatting --- src/AESCryptoServiceProvider.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/AESCryptoServiceProvider.php b/src/AESCryptoServiceProvider.php index fb55044..e06eb9b 100644 --- a/src/AESCryptoServiceProvider.php +++ b/src/AESCryptoServiceProvider.php @@ -119,11 +119,30 @@ public function encrypt(string $plainText, bool $legacy = false): string $this->tag ); - if ($legacy) { - return base64_encode($this->iv . $this->tag . $encryptedBytes); - } + return base64_encode($this->buildPayload( + iv: $this->iv, + tag: $this->tag, + encryptedData: $encryptedBytes, + legacy: $legacy + )); + } - return base64_encode($this->iv . $encryptedBytes . $this->tag); + /** + * Build payload for encrypted data + * + * @param string $iv + * @param string $tag + * @param string $encryptedData + * @param bool $legacy + * If true, returns IV-TAG-EncryptedData format + * If false, returns IV-EncryptedData-TAG format + * @return string + */ + protected function buildPayload(string $iv, string $tag, string $encryptedData, bool $legacy): string + { + return $legacy + ? $iv . $tag . $encryptedData // IV-TAG-EncryptedData + : $iv . $encryptedData . $tag; // IV-EncryptedData-TAG } /** From f7cacde0d95da308cb879962a9ba3b93f4b48615 Mon Sep 17 00:00:00 2001 From: May Meow <3164256+MayMeow@users.noreply.github.com> Date: Wed, 4 Jun 2025 11:07:43 +0000 Subject: [PATCH 6/6] Refactor decrypt method to use parsePayload for improved clarity and maintainability --- src/AESCryptoServiceProvider.php | 36 ++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/AESCryptoServiceProvider.php b/src/AESCryptoServiceProvider.php index e06eb9b..0c44a56 100644 --- a/src/AESCryptoServiceProvider.php +++ b/src/AESCryptoServiceProvider.php @@ -166,17 +166,11 @@ public function decrypt(string $encryptedData, bool $legacy = false): string throw new IvGenerateException(); } - $this->iv = substr($c, 0, $iv_len); - - if ($legacy) { - // IV-TAG-EncryptedData - $this->tag = substr($c, $iv_len, static::DEFAULT_GCM_TAG_LENGTH); // tag is 16 bytes after iv - $encryptedBytes = substr($c, $iv_len + static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are at the end - } else { - // IV-EncryptedData-TAG - $encryptedBytes = substr($c, $iv_len, -static::DEFAULT_GCM_TAG_LENGTH); // encrypted data are in the middle - $this->tag = substr($c, -static::DEFAULT_GCM_TAG_LENGTH); // tag is at the end - } + [$this->iv, $encryptedBytes, $this->tag] = $this->parsePayload( + cipherText: $c, + ivLength: $iv_len, + legacy: $legacy + ); $decryptedText = openssl_decrypt( $encryptedBytes, @@ -194,6 +188,26 @@ public function decrypt(string $encryptedData, bool $legacy = false): string return $decryptedText; } + /** + * Parse payload from encrypted data + * + * @param string $cipherText + * @param int $ivLength + * @param bool $legacy + * If true, expects IV-TAG-EncryptedData format + * If false, expects IV-EncryptedData-TAG format + * @return array That contains IV, EncryptedData and TAG in that order + */ + protected function parsePayload(string $cipherText, int $ivLength, bool $legacy = false): array + { + $iv = substr($cipherText, 0, $ivLength); + $tagLength = static::DEFAULT_GCM_TAG_LENGTH; + + return $legacy + ? [$iv, substr($cipherText, $ivLength + $tagLength), substr($cipherText, $ivLength, $tagLength)] + : [$iv, substr($cipherText, $ivLength, -$tagLength), substr($cipherText, -$tagLength)]; + } + /** * Seal data using AES-256-CBC and public key *