Skip to content

Commit d5e092b

Browse files
committed
refactor: remove twice lowercase
1 parent 665b91b commit d5e092b

File tree

3 files changed

+51
-39
lines changed

3 files changed

+51
-39
lines changed

.php-cs-fixer.dist.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,5 @@
3838
'PHPDevsr/PHPSpreadsheet-Secure',
3939
'Denny Septian Panggabean',
4040
41-
2024
41+
2024,
4242
);

phpstan-baseline.php

+12
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,18 @@
163163
'count' => 1,
164164
'path' => __DIR__ . '/src/Secure.php',
165165
];
166+
$ignoreErrors[] = [
167+
'message' => '#^Strict comparison using \\=\\=\\= between \'AES\' and \'AES\' will always evaluate to true\\.$#',
168+
'identifier' => 'identical.alwaysTrue',
169+
'count' => 1,
170+
'path' => __DIR__ . '/src/Secure.php',
171+
];
172+
$ignoreErrors[] = [
173+
'message' => '#^Strict comparison using \\=\\=\\= between \'SHA512\' and \'SHA512\' will always evaluate to true\\.$#',
174+
'identifier' => 'identical.alwaysTrue',
175+
'count' => 1,
176+
'path' => __DIR__ . '/src/Secure.php',
177+
];
166178
$ignoreErrors[] = [
167179
'message' => '#^Parameter \\#2 \\$length of function fread expects int\\<1, max\\>, int\\<0, max\\> given\\.$#',
168180
'identifier' => 'argument.type',

src/Secure.php

+38-38
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)