2222 */
2323class PasswordEncoder
2424{
25+ const ALGORITHM_MD2 = 'MD2 ' ;
26+ const ALGORITHM_MD4 = 'MD4 ' ;
27+ const ALGORITHM_MD5 = 'MD5 ' ;
28+ const ALGORITHM_SHA_1 = 'SHA-1 ' ;
29+ const ALGORITHM_SHA_256 = 'SHA-256 ' ;
30+ const ALGORITHM_SHA_384 = 'SHA-384 ' ;
31+ const ALGORITHM_SHA_512 = 'SHA-512 ' ;
32+ const ALGORITHM_RIPEMD = 'RIPEMD ' ;
33+ const ALGORITHM_RIPEMD_160 = 'RIPEMD-160 ' ;
34+ const ALGORITHM_MAC = 'MAC ' ;
35+ const ALGORITHM_HMAC = 'HMAC ' ;
36+
37+ /**
38+ * Mapping between algorithm name and algorithm ID
39+ *
40+ * @var array
41+ * @see https://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.writeprotection.cryptographicalgorithmsid(v=office.14).aspx
42+ */
2543 private static $ algorithmMapping = array (
26- 1 => 'md2 ' ,
27- 2 => 'md4 ' ,
28- 3 => 'md5 ' ,
29- 4 => 'sha1 ' ,
30- 5 => '' , // 'mac' -> not possible with hash()
31- 6 => 'ripemd ' ,
32- 7 => 'ripemd160 ' ,
33- 8 => '' ,
34- 9 => '' , //'hmac' -> not possible with hash()
35- 10 => '' ,
36- 11 => '' ,
37- 12 => 'sha256 ' ,
38- 13 => 'sha384 ' ,
39- 14 => 'sha512 ' ,
44+ self ::ALGORITHM_MD2 => array (1 , 'md2 ' ),
45+ self ::ALGORITHM_MD4 => array (2 , 'md4 ' ),
46+ self ::ALGORITHM_MD5 => array (3 , 'md5 ' ),
47+ self ::ALGORITHM_SHA_1 => array (4 , 'sha1 ' ),
48+ self ::ALGORITHM_MAC => array (5 , '' ), // 'mac' -> not possible with hash()
49+ self ::ALGORITHM_RIPEMD => array (6 , 'ripemd ' ),
50+ self ::ALGORITHM_RIPEMD_160 => array (7 , 'ripemd160 ' ),
51+ self ::ALGORITHM_HMAC => array (9 , '' ), //'hmac' -> not possible with hash()
52+ self ::ALGORITHM_SHA_256 => array (12 , 'sha256 ' ),
53+ self ::ALGORITHM_SHA_384 => array (13 , 'sha384 ' ),
54+ self ::ALGORITHM_SHA_512 => array (14 , 'sha512 ' ),
4055 );
4156
4257 private static $ initialCodeArray = array (
@@ -82,12 +97,12 @@ class PasswordEncoder
8297 * @see https://blogs.msdn.microsoft.com/vsod/2010/04/05/how-to-set-the-editing-restrictions-in-word-using-open-xml-sdk-2-0/
8398 *
8499 * @param string $password
85- * @param integer $algorithmSid
100+ * @param string $algorithmName
86101 * @param string $salt
87102 * @param integer $spinCount
88103 * @return string
89104 */
90- public static function hashPassword ($ password , $ algorithmSid = 4 , $ salt = null , $ spinCount = 10000 )
105+ public static function hashPassword ($ password , $ algorithmName = PasswordEncoder:: ALGORITHM_SHA_1 , $ salt = null , $ spinCount = 10000 )
91106 {
92107 $ origEncoding = mb_internal_encoding ();
93108 mb_internal_encoding ('UTF-8 ' );
@@ -118,7 +133,7 @@ public static function hashPassword($password, $algorithmSid = 4, $salt = null,
118133 // Implementation Notes List:
119134 // Word requires that the initial hash of the password with the salt not be considered in the count.
120135 // The initial hash of salt + key is not included in the iteration count.
121- $ algorithm = self ::getAlgorithm ($ algorithmSid );
136+ $ algorithm = self ::getAlgorithm ($ algorithmName );
122137 $ generatedKey = hash ($ algorithm , $ salt . $ generatedKey , true );
123138
124139 for ($ i = 0 ; $ i < $ spinCount ; $ i ++) {
@@ -134,12 +149,12 @@ public static function hashPassword($password, $algorithmSid = 4, $salt = null,
134149 /**
135150 * Get algorithm from self::$algorithmMapping
136151 *
137- * @param int $sid
152+ * @param string $algorithmName
138153 * @return string
139154 */
140- private static function getAlgorithm ($ sid )
155+ private static function getAlgorithm ($ algorithmName )
141156 {
142- $ algorithm = self ::$ algorithmMapping [$ sid ];
157+ $ algorithm = self ::$ algorithmMapping [$ algorithmName ][ 1 ];
143158 if ($ algorithm == '' ) {
144159 $ algorithm = 'sha1 ' ;
145160 }
0 commit comments