@@ -71,7 +71,7 @@ public function __construct(
7171 /**
7272 * Check using binary?
7373 */
74- public bool $ NOFILE = false
74+ public bool $ NOFILE = false ,
7575 ) {
7676 }
7777
@@ -149,20 +149,25 @@ public function output(?string $filePath = null)
149149 'cipherAlgorithm ' => 'AES ' , // Cipher algorithm to use. Excel uses AES.
150150 'cipherChaining ' => 'ChainingModeCBC ' , // Cipher chaining mode to use. Excel uses CBC.
151151 'saltValue ' => (array ) unpack ('C* ' , random_bytes (16 )), // Random value to use as encryption salt. Excel uses 16 bytes.
152- 'hashAlgorithm ' => 'sha512 ' , // Hash algorithm to use. Excel uses SHA512.
152+ 'hashAlgorithm ' => 'SHA512 ' , // Hash algorithm to use. Excel uses SHA512.
153153 'hashSize ' => 64 , // The size of the hash in bytes. SHA512 results in 64-byte hashes
154154 'blockSize ' => 16 , // The number of bytes used to encrypt one block of data. It MUST be at least 2, no greater than 4096, and a multiple of 2. Excel uses 16
155155 'spinCount ' => 100000 , // The number of times to iterate on a hash of a password. It MUST NOT be greater than 10,000,000. Excel uses 100,000.
156156 'keyBits ' => 256 , // The length of the key to generate from the password. Must be a multiple of 8. Excel uses 256.
157157 ],
158158 ];
159159
160+ $ lowerKeyHashAlgo = \strtolower ($ encryptionInfo ['key ' ]['hashAlgorithm ' ]);
161+ $ lowerPackageHashAlgo = $ encryptionInfo ['key ' ]['hashAlgorithm ' ] === $ encryptionInfo ['package ' ]['hashAlgorithm ' ] ? $ lowerKeyHashAlgo : \strtolower ($ encryptionInfo ['package ' ]['hashAlgorithm ' ]);
162+ $ lowerKeyCipherAlgo = \strtolower ($ encryptionInfo ['key ' ]['cipherAlgorithm ' ]);
163+ $ lowerPackageCipherAlgo = $ encryptionInfo ['key ' ]['cipherAlgorithm ' ] === $ encryptionInfo ['package ' ]['cipherAlgorithm ' ] ? $ lowerKeyCipherAlgo : \strtolower ($ encryptionInfo ['package ' ]['cipherAlgorithm ' ]);
164+
160165 // Package Encryption
161166 $ encryptedPackage = $ this ->_cryptPackage (
162167 true ,
163- $ encryptionInfo [ ' package ' ][ ' cipherAlgorithm ' ] ,
168+ $ lowerPackageCipherAlgo ,
164169 $ encryptionInfo ['package ' ]['cipherChaining ' ],
165- $ encryptionInfo [ ' package ' ][ ' hashAlgorithm ' ] ,
170+ $ lowerPackageHashAlgo ,
166171 $ encryptionInfo ['package ' ]['blockSize ' ],
167172 $ encryptionInfo ['package ' ]['saltValue ' ],
168173 $ this ->data ,
@@ -179,41 +184,41 @@ public function output(?string $filePath = null)
179184 $ hmacKey = unpack ('C* ' , random_bytes (64 ));
180185 // Then create an initialization vector using the package encryption info and the appropriate block key.
181186 $ hmacKeyIV = $ this ->_createIV (
182- $ encryptionInfo [ ' package ' ][ ' hashAlgorithm ' ] ,
187+ $ lowerPackageHashAlgo ,
183188 $ encryptionInfo ['package ' ]['saltValue ' ],
184189 $ encryptionInfo ['package ' ]['blockSize ' ],
185- $ this ->_block_keys ['dataIntegrity ' ]['hmacKey ' ]
190+ $ this ->_block_keys ['dataIntegrity ' ]['hmacKey ' ],
186191 );
187192
188193 // Use the package key and the IV to encrypt the HMAC key
189194 $ encryptedHmacKey = $ this ->_crypt (
190195 true ,
191- $ encryptionInfo [ ' package ' ][ ' cipherAlgorithm ' ] ,
196+ $ lowerPackageCipherAlgo ,
192197 $ encryptionInfo ['package ' ]['cipherChaining ' ],
193198 $ packageKey ,
194199 $ hmacKeyIV ,
195- $ hmacKey
200+ $ hmacKey,
196201 );
197202
198203 // Now create the HMAC
199- $ hmacValue = $ this ->_hmac ($ encryptionInfo [ ' package ' ][ ' hashAlgorithm ' ] , $ hmacKey , $ encryptedPackage ['tmpFile ' ]);
204+ $ hmacValue = $ this ->_hmac ($ lowerPackageHashAlgo , $ hmacKey , $ encryptedPackage ['tmpFile ' ]);
200205
201206 // Next generate an initialization vector for encrypting the resulting HMAC value.
202207 $ hmacValueIV = $ this ->_createIV (
203- $ encryptionInfo [ ' package ' ][ ' hashAlgorithm ' ] ,
208+ $ lowerPackageHashAlgo ,
204209 $ encryptionInfo ['package ' ]['saltValue ' ],
205210 $ encryptionInfo ['package ' ]['blockSize ' ],
206- $ this ->_block_keys ['dataIntegrity ' ]['hmacValue ' ]
211+ $ this ->_block_keys ['dataIntegrity ' ]['hmacValue ' ],
207212 );
208213
209214 // Now encrypt the value
210215 $ encryptedHmacValue = $ this ->_crypt (
211216 true ,
212- $ encryptionInfo [ ' package ' ][ ' cipherAlgorithm ' ] ,
217+ $ lowerPackageCipherAlgo ,
213218 $ encryptionInfo ['package ' ]['cipherChaining ' ],
214219 $ packageKey ,
215220 $ hmacValueIV ,
216- $ hmacValue
221+ $ hmacValue,
217222 );
218223
219224 // Put the encrypted key and value on the encryption info
@@ -227,21 +232,21 @@ public function output(?string $filePath = null)
227232 // Convert the password to an encryption key
228233 $ key = $ this ->_convertPasswordToKey (
229234 $ password ,
230- $ encryptionInfo [ ' key ' ][ ' hashAlgorithm ' ] ,
235+ $ lowerKeyHashAlgo ,
231236 $ encryptionInfo ['key ' ]['saltValue ' ],
232237 $ encryptionInfo ['key ' ]['spinCount ' ],
233238 $ encryptionInfo ['key ' ]['keyBits ' ],
234- $ this ->_block_keys ['key ' ]
239+ $ this ->_block_keys ['key ' ],
235240 );
236241
237242 // // Encrypt the package key with the
238243 $ encryptionInfo ['key ' ]['encryptedKeyValue ' ] = $ this ->_crypt (
239244 true ,
240- $ encryptionInfo [ ' key ' ][ ' cipherAlgorithm ' ] ,
245+ $ lowerKeyCipherAlgo ,
241246 $ encryptionInfo ['key ' ]['cipherChaining ' ],
242247 $ key ,
243248 $ encryptionInfo ['key ' ]['saltValue ' ],
244- $ packageKey
249+ $ packageKey,
245250 );
246251
247252 // Verifier hash with random byte array for hashing
@@ -250,44 +255,44 @@ public function output(?string $filePath = null)
250255 // Create an encryption key from the password for the input
251256 $ verifierHashInputKey = $ this ->_convertPasswordToKey (
252257 $ password ,
253- $ encryptionInfo [ ' key ' ][ ' hashAlgorithm ' ] ,
258+ $ lowerKeyHashAlgo ,
254259 $ encryptionInfo ['key ' ]['saltValue ' ],
255260 $ encryptionInfo ['key ' ]['spinCount ' ],
256261 $ encryptionInfo ['key ' ]['keyBits ' ],
257- $ this ->_block_keys ['verifierHash ' ]['input ' ]
262+ $ this ->_block_keys ['verifierHash ' ]['input ' ],
258263 );
259264
260265 // Use the key to encrypt the verifier input
261266 $ encryptionInfo ['key ' ]['encryptedVerifierHashInput ' ] = $ this ->_crypt (
262267 true ,
263- $ encryptionInfo [ ' key ' ][ ' cipherAlgorithm ' ] ,
268+ $ lowerKeyCipherAlgo ,
264269 $ encryptionInfo ['key ' ]['cipherChaining ' ],
265270 $ verifierHashInputKey ,
266271 $ encryptionInfo ['key ' ]['saltValue ' ],
267- $ verifierHashInput
272+ $ verifierHashInput,
268273 );
269274
270275 // Create a hash of the input
271- $ verifierHashValue = $ this ->_hash ($ encryptionInfo [ ' key ' ][ ' hashAlgorithm ' ] , $ verifierHashInput );
276+ $ verifierHashValue = $ this ->_hash ($ lowerKeyHashAlgo , $ verifierHashInput );
272277
273278 // Create an encryption key from the password for the hash
274279 $ verifierHashValueKey = $ this ->_convertPasswordToKey (
275280 $ password ,
276- $ encryptionInfo [ ' key ' ][ ' hashAlgorithm ' ] ,
281+ $ lowerKeyHashAlgo ,
277282 $ encryptionInfo ['key ' ]['saltValue ' ],
278283 $ encryptionInfo ['key ' ]['spinCount ' ],
279284 $ encryptionInfo ['key ' ]['keyBits ' ],
280- $ this ->_block_keys ['verifierHash ' ]['value ' ]
285+ $ this ->_block_keys ['verifierHash ' ]['value ' ],
281286 );
282287
283288 // Use the key to encrypt the hash value
284289 $ encryptionInfo ['key ' ]['encryptedVerifierHashValue ' ] = $ this ->_crypt (
285290 true ,
286- $ encryptionInfo [ ' key ' ][ ' cipherAlgorithm ' ] ,
291+ $ lowerKeyCipherAlgo ,
287292 $ encryptionInfo ['key ' ]['cipherChaining ' ],
288293 $ verifierHashValueKey ,
289294 $ encryptionInfo ['key ' ]['saltValue ' ],
290- $ verifierHashValue
295+ $ verifierHashValue,
291296 );
292297
293298 // Build the encryption info buffer
@@ -430,7 +435,7 @@ private function arrayToXml(array $array = [])
430435 */
431436 private function _crypt ($ encrypt , $ cipherAlgorithm , $ cipherChaining , $ key , $ iv , $ input )
432437 {
433- $ algorithm = strtolower ( $ cipherAlgorithm) . '- ' . (count ($ key ) * 8 );
438+ $ algorithm = $ cipherAlgorithm . '- ' . (count ($ key ) * 8 );
434439
435440 if ($ cipherChaining === 'ChainingModeCBC ' ) {
436441 $ algorithm .= '-cbc ' ;
@@ -446,7 +451,7 @@ private function _crypt($encrypt, $cipherAlgorithm, $cipherChaining, $key, $iv,
446451 $ algorithm ,
447452 pack ('C* ' , ...$ key ),
448453 OPENSSL_NO_PADDING ,
449- pack ('C* ' , ...$ iv )
454+ pack ('C* ' , ...$ iv ),
450455 );
451456 $ cipher = (array ) unpack ('C* ' , (string ) $ ciphertext );
452457 }
@@ -463,8 +468,7 @@ private function _crypt($encrypt, $cipherAlgorithm, $cipherChaining, $key, $iv,
463468 */
464469 private function _hash ($ algorithm , ...$ buffers )
465470 {
466- $ algorithm = strtolower ($ algorithm );
467- $ buffers = array_merge ([], ...$ buffers );
471+ $ buffers = [...[], ...$ buffers ];
468472
469473 if (! in_array ($ algorithm , hash_algos (), true )) {
470474 throw new Exception ("Hash algorithm ' {$ algorithm }' not supported! " ); // @codeCoverageIgnore
@@ -489,10 +493,10 @@ private function _hash($algorithm, ...$buffers)
489493 private function _hmac ($ algorithm , $ key , $ fileName )
490494 {
491495 return (array ) unpack ('C* ' , hash_hmac_file (
492- strtolower ( $ algorithm) ,
496+ $ algorithm ,
493497 $ fileName ,
494498 pack ('C* ' , ...$ key ),
495- true
499+ true ,
496500 ));
497501 }
498502
@@ -511,20 +515,16 @@ private function _convertPasswordToKey($password, $hashAlgorithm, $saltValue, $s
511515 {
512516 // Password must be in unicode buffer
513517 $ passwordBuffer = array_map ('hexdec ' , str_split (bin2hex (mb_convert_encoding ($ password , 'UTF-16LE ' , 'utf-8 ' )), 2 ));
518+
514519 // Generate the initial hash
515520 $ key = $ this ->_hash ($ hashAlgorithm , $ saltValue , $ passwordBuffer );
516521
517- // Now regenerate until spin count
518- // Prepare for hash(). Algo is known to be OK. Previous call to _hash()
519- // would have thrown an exception if not.
520- $ algo = strtolower ($ hashAlgorithm );
521-
522522 // Get back to a binary string
523523 $ bKey = pack ('C* ' , ...$ key );
524524
525525 // Now regenerate until spin count
526526 for ($ i = 0 ; $ i < $ spinCount ; $ i ++) {
527- $ bKey = hash ($ algo , pack ('V ' , $ i ) . $ bKey , true );
527+ $ bKey = hash ($ hashAlgorithm , pack ('V ' , $ i ) . $ bKey , true );
528528 }
529529
530530 // Convert binary string back to unpacked C* form
0 commit comments