PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Shared / PasswordHasher.php

PasswordHasher.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Shared/PasswordHasher.php

107 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Shared;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Exception as SpException;
6 use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Protection;
7
8 class PasswordHasher
9 {
10 const MAX_PASSWORD_LENGTH = 255;
11
12 /**
13 * Get algorithm name for PHP.
14 */
15 private static function getAlgorithm(string $algorithmName): string
16 {
17 if (!$algorithmName) {
18 return '';
19 }
20
21 // Mapping between algorithm name in Excel and algorithm name in PHP
22 $mapping = [
23 Protection::ALGORITHM_MD2 => 'md2',
24 Protection::ALGORITHM_MD4 => 'md4',
25 Protection::ALGORITHM_MD5 => 'md5',
26 Protection::ALGORITHM_SHA_1 => 'sha1',
27 Protection::ALGORITHM_SHA_256 => 'sha256',
28 Protection::ALGORITHM_SHA_384 => 'sha384',
29 Protection::ALGORITHM_SHA_512 => 'sha512',
30 Protection::ALGORITHM_RIPEMD_128 => 'ripemd128',
31 Protection::ALGORITHM_RIPEMD_160 => 'ripemd160',
32 Protection::ALGORITHM_WHIRLPOOL => 'whirlpool',
33 ];
34
35 if (array_key_exists($algorithmName, $mapping)) {
36 return $mapping[$algorithmName];
37 }
38
39 throw new SpException('Unsupported password algorithm: ' . $algorithmName);
40 }
41
42 /**
43 * Create a password hash from a given string.
44 *
45 * This method is based on the spec at:
46 * https://interoperability.blob.core.windows.net/files/MS-OFFCRYPTO/[MS-OFFCRYPTO].pdf
47 * 2.3.7.1 Binary Document Password Verifier Derivation Method 1
48 *
49 * It replaces a method based on the algorithm provided by
50 * Daniel Rentz of OpenOffice and the PEAR package
51 * Spreadsheet_Excel_Writer by Xavier Noguer <[email protected]>.
52 *
53 * @param string $password Password to hash
54 */
55 private static function defaultHashPassword(string $password): string
56 {
57 $verifier = 0;
58 $pwlen = strlen($password);
59 $passwordArray = pack('c', $pwlen) . $password;
60 for ($i = $pwlen; $i >= 0; --$i) {
61 $intermediate1 = (($verifier & 0x4000) === 0) ? 0 : 1;
62 $intermediate2 = 2 * $verifier;
63 $intermediate2 = $intermediate2 & 0x7FFF;
64 $intermediate3 = $intermediate1 | $intermediate2;
65 $verifier = $intermediate3 ^ ord($passwordArray[$i]);
66 }
67 $verifier ^= 0xCE4B;
68
69 return strtoupper(dechex($verifier));
70 }
71
72 /**
73 * Create a password hash from a given string by a specific algorithm.
74 *
75 * 2.4.2.4 ISO Write Protection Method
76 *
77 * @see https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/1357ea58-646e-4483-92ef-95d718079d6f
78 *
79 * @param string $password Password to hash
80 * @param string $algorithm Hash algorithm used to compute the password hash value
81 * @param string $salt Pseudorandom base64-encoded string
82 * @param int $spinCount Number of times to iterate on a hash of a password
83 *
84 * @return string Hashed password
85 */
86 public static function hashPassword(string $password, string $algorithm = '', string $salt = '', int $spinCount = 10000): string
87 {
88 if (strlen($password) > self::MAX_PASSWORD_LENGTH) {
89 throw new SpException('Password exceeds ' . self::MAX_PASSWORD_LENGTH . ' characters');
90 }
91 $phpAlgorithm = self::getAlgorithm($algorithm);
92 if (!$phpAlgorithm) {
93 return self::defaultHashPassword($password);
94 }
95
96 $saltValue = base64_decode($salt);
97 $encodedPassword = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8');
98
99 $hashValue = hash($phpAlgorithm, $saltValue . $encodedPassword, true);
100 for ($i = 0; $i < $spinCount; ++$i) {
101 $hashValue = hash($phpAlgorithm, $hashValue . pack('L', $i), true);
102 }
103
104 return base64_encode($hashValue);
105 }
106 }
107