@@ -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 *
0 commit comments