Skip to content

Commit 0b8816d

Browse files
authored
Merge pull request #30 from MayMeow/dev/fix-29
Add legacy support for encryption and decryption methods in AES CyriptoService provider
2 parents fc6db57 + f7cacde commit 0b8816d

File tree

2 files changed

+59
-6
lines changed

2 files changed

+59
-6
lines changed

src/AESCryptoServiceProvider.php

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,12 @@ public function generateIV(?string $cipher = null)
103103
* Returns encrypted text
104104
*
105105
* @param string $plainText
106+
* @param bool $legacy
107+
* If true, returns IV-TAG-EncryptedData format
108+
* If false, returns IV-EncryptedData-TAG format
106109
* @return string
107110
*/
108-
public function encrypt(string $plainText): string
111+
public function encrypt(string $plainText, bool $legacy = false): string
109112
{
110113
$encryptedBytes = openssl_encrypt(
111114
$plainText,
@@ -116,18 +119,44 @@ public function encrypt(string $plainText): string
116119
$this->tag
117120
);
118121

119-
return base64_encode($this->iv . $this->tag . $encryptedBytes);
122+
return base64_encode($this->buildPayload(
123+
iv: $this->iv,
124+
tag: $this->tag,
125+
encryptedData: $encryptedBytes,
126+
legacy: $legacy
127+
));
128+
}
129+
130+
/**
131+
* Build payload for encrypted data
132+
*
133+
* @param string $iv
134+
* @param string $tag
135+
* @param string $encryptedData
136+
* @param bool $legacy
137+
* If true, returns IV-TAG-EncryptedData format
138+
* If false, returns IV-EncryptedData-TAG format
139+
* @return string
140+
*/
141+
protected function buildPayload(string $iv, string $tag, string $encryptedData, bool $legacy): string
142+
{
143+
return $legacy
144+
? $iv . $tag . $encryptedData // IV-TAG-EncryptedData
145+
: $iv . $encryptedData . $tag; // IV-EncryptedData-TAG
120146
}
121147

122148
/**
123149
* Decrypt given text
124150
*
125151
* @param string $encryptedData
152+
* @param bool $legacy
153+
* If true, expects IV-TAG-EncryptedData format
154+
* If false, expects IV-EncryptedData-TAG format
126155
* @return string
127156
* @throws DecryptException
128157
* @throws IvGenerateException
129158
*/
130-
public function decrypt(string $encryptedData): string
159+
public function decrypt(string $encryptedData, bool $legacy = false): string
131160
{
132161
$c = base64_decode($encryptedData);
133162

@@ -137,9 +166,11 @@ public function decrypt(string $encryptedData): string
137166
throw new IvGenerateException();
138167
}
139168

140-
$this->iv = substr($c, 0, $iv_len);
141-
$this->tag = substr($c, $iv_len, static::DEFAULT_GCM_TAG_LENGTH);
142-
$encryptedBytes = substr($c, $iv_len + static::DEFAULT_GCM_TAG_LENGTH);
169+
[$this->iv, $encryptedBytes, $this->tag] = $this->parsePayload(
170+
cipherText: $c,
171+
ivLength: $iv_len,
172+
legacy: $legacy
173+
);
143174

144175
$decryptedText = openssl_decrypt(
145176
$encryptedBytes,
@@ -157,6 +188,26 @@ public function decrypt(string $encryptedData): string
157188
return $decryptedText;
158189
}
159190

191+
/**
192+
* Parse payload from encrypted data
193+
*
194+
* @param string $cipherText
195+
* @param int $ivLength
196+
* @param bool $legacy
197+
* If true, expects IV-TAG-EncryptedData format
198+
* If false, expects IV-EncryptedData-TAG format
199+
* @return array That contains IV, EncryptedData and TAG in that order
200+
*/
201+
protected function parsePayload(string $cipherText, int $ivLength, bool $legacy = false): array
202+
{
203+
$iv = substr($cipherText, 0, $ivLength);
204+
$tagLength = static::DEFAULT_GCM_TAG_LENGTH;
205+
206+
return $legacy
207+
? [$iv, substr($cipherText, $ivLength + $tagLength), substr($cipherText, $ivLength, $tagLength)]
208+
: [$iv, substr($cipherText, $ivLength, -$tagLength), substr($cipherText, -$tagLength)];
209+
}
210+
160211
/**
161212
* Seal data using AES-256-CBC and public key
162213
*

tests/AESCryptoServiceProviderTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ public function textCanBeEncryptedAndDecrypted() : void
1616

1717
$plainText = "This is going to be encrypted!";
1818
$encryptedText= $csp->encrypt($plainText);
19+
$encryptedTextLegacy = $csp->encrypt($plainText, legacy: true);
1920

2021
$csp2 = new AESCryptoServiceProvider();
2122
$csp2->setKey($key);
2223

2324
$this->assertEquals($plainText, $csp2->decrypt($encryptedText));
25+
$this->assertEquals($plainText, $csp2->decrypt($encryptedTextLegacy, legacy: true));
2426
}
2527
}

0 commit comments

Comments
 (0)