@@ -163,10 +163,19 @@ public function decrypt($payload, $unserialize = true)
163
163
$ tag = empty ($ payload ['tag ' ]) ? null : base64_decode ($ payload ['tag ' ])
164
164
);
165
165
166
+ $ foundValidMac = false ;
167
+
166
168
// Here we will decrypt the value. If we are able to successfully decrypt it
167
169
// we will then unserialize it and return it out to the caller. If we are
168
170
// unable to decrypt this value we will throw out an exception message.
169
171
foreach ($ this ->getAllKeys () as $ key ) {
172
+ if (
173
+ $ this ->shouldValidateMac () &&
174
+ ! ($ foundValidMac = $ foundValidMac || $ this ->validMacForKey ($ payload , $ key ))
175
+ ) {
176
+ continue ;
177
+ }
178
+
170
179
$ decrypted = \openssl_decrypt (
171
180
$ payload ['value ' ], strtolower ($ this ->cipher ), $ key , 0 , $ iv , $ tag ?? ''
172
181
);
@@ -176,7 +185,11 @@ public function decrypt($payload, $unserialize = true)
176
185
}
177
186
}
178
187
179
- if ($ decrypted === false ) {
188
+ if ($ this ->shouldValidateMac () && ! $ foundValidMac ) {
189
+ throw new DecryptException ('The MAC is invalid. ' );
190
+ }
191
+
192
+ if (($ decrypted ?? false ) === false ) {
180
193
throw new DecryptException ('Could not decrypt the data. ' );
181
194
}
182
195
@@ -232,10 +245,6 @@ protected function getJsonPayload($payload)
232
245
throw new DecryptException ('The payload is invalid. ' );
233
246
}
234
247
235
- if (! self ::$ supportedCiphers [strtolower ($ this ->cipher )]['aead ' ] && ! $ this ->validMac ($ payload )) {
236
- throw new DecryptException ('The MAC is invalid. ' );
237
- }
238
-
239
248
return $ payload ;
240
249
}
241
250
@@ -265,24 +274,28 @@ protected function validPayload($payload)
265
274
}
266
275
267
276
/**
268
- * Determine if the MAC for the given payload is valid.
277
+ * Determine if the MAC for the given payload is valid for the primary key .
269
278
*
270
279
* @param array $payload
271
280
* @return bool
272
281
*/
273
282
protected function validMac (array $ payload )
274
283
{
275
- foreach ($ this ->getAllKeys () as $ key ) {
276
- $ valid = hash_equals (
277
- $ this ->hash ($ payload ['iv ' ], $ payload ['value ' ], $ key ), $ payload ['mac ' ]
278
- );
279
-
280
- if ($ valid === true ) {
281
- return true ;
282
- }
283
- }
284
+ return $ this ->validMacForKey ($ payload , $ this ->key );
285
+ }
284
286
285
- return false ;
287
+ /**
288
+ * Determine if the MAC is valid for the given payload and key.
289
+ *
290
+ * @param array $payload
291
+ * @param string $key
292
+ * @return bool
293
+ */
294
+ protected function validMacForKey ($ payload , $ key )
295
+ {
296
+ return hash_equals (
297
+ $ this ->hash ($ payload ['iv ' ], $ payload ['value ' ], $ key ), $ payload ['mac ' ]
298
+ );
286
299
}
287
300
288
301
/**
@@ -302,6 +315,16 @@ protected function ensureTagIsValid($tag)
302
315
}
303
316
}
304
317
318
+ /**
319
+ * Determine if we should validate the MAC while decrypting.
320
+ *
321
+ * @return bool
322
+ */
323
+ protected function shouldValidateMac ()
324
+ {
325
+ return ! self ::$ supportedCiphers [strtolower ($ this ->cipher )]['aead ' ];
326
+ }
327
+
305
328
/**
306
329
* Get the encryption key that the encrypter is currently using.
307
330
*
0 commit comments