Skip to content

Commit 71574d1

Browse files
author
Lenz Weber
committed
Code Review; minor changes to salt handling, corrected some comments
1 parent 7624663 commit 71574d1

File tree

2 files changed

+16
-22
lines changed

2 files changed

+16
-22
lines changed

src/PhpWord/Metadata/Protection.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Protection
3434
private $editing;
3535

3636
/**
37-
* Hashed password
37+
* password
3838
*
3939
* @var string
4040
*/
@@ -55,7 +55,7 @@ class Protection
5555
private $mswordAlgorithmSid = 4;
5656

5757
/**
58-
* Hashed salt
58+
* salt
5959
*
6060
* @var string
6161
*/
@@ -95,7 +95,7 @@ public function setEditing($editing = null)
9595
}
9696

9797
/**
98-
* Get password hash
98+
* Get password
9999
*
100100
* @return string
101101
*/
@@ -164,7 +164,7 @@ public function setMswordAlgorithmSid($mswordAlgorithmSid)
164164
}
165165

166166
/**
167-
* Get salt hash
167+
* Get salt
168168
*
169169
* @return string
170170
*/
@@ -174,13 +174,18 @@ public function getSalt()
174174
}
175175

176176
/**
177-
* Set salt hash
177+
* Set salt. Salt HAS to be 16 characters, or an exception will be thrown.
178178
*
179179
* @param $salt
180180
* @return self
181+
* @throws \InvalidArgumentException
181182
*/
182183
public function setSalt($salt)
183184
{
185+
if ($salt !== null && strlen($salt) !== 16){
186+
throw new \InvalidArgumentException('salt has to be of exactly 16 bytes length');
187+
}
188+
184189
$this->salt = $salt;
185190

186191
return $this;

src/PhpWord/Writer/Word2007/Part/Settings.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ private function getProtection()
225225
'w:cryptAlgorithmType' => 'typeAny',
226226
'w:cryptAlgorithmSid' => $protection->getMswordAlgorithmSid(),
227227
'w:cryptSpinCount' => $protection->getSpinCount(),
228-
'w:hash' => $this->getPasswordHash($protection),
229-
'w:salt' => $this->getSaltHash($protection->getSalt()),
228+
'w:hash' => $this->getEncodedPasswordHash($protection),
229+
'w:salt' => base64_encode($protection->getSalt()),
230230
)
231231
);
232232
}
@@ -255,19 +255,19 @@ private function getCompatibility()
255255

256256
/**
257257
* Create a hashed password that MS Word will be able to work with
258+
* @link https://blogs.msdn.microsoft.com/vsod/2010/04/05/how-to-set-the-editing-restrictions-in-word-using-open-xml-sdk-2-0/
258259
*
259260
* @param \PhpOffice\PhpWord\Metadata\Protection $protection
260261
* @return string
261262
*/
262-
private function getPasswordHash($protection)
263+
private function getEncodedPasswordHash($protection)
263264
{
264265
$orig_encoding = mb_internal_encoding();
265266
mb_internal_encoding("UTF-8");
266267

267268
$password = $protection->getPassword();
268269
$password = mb_substr($password, 0, min(self::$passwordMaxLength, mb_strlen($password)));
269270

270-
// Construct a new NULL-terminated string consisting of single-byte characters:
271271
// Get the single-byte values by iterating through the Unicode characters of the truncated password.
272272
// For each character, if the low byte is not equal to 0, take it. Otherwise, take the high byte.
273273
$pass_utf8 = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8');
@@ -291,7 +291,7 @@ private function getPasswordHash($protection)
291291
// Word requires that the initial hash of the password with the salt not be considered in the count.
292292
// The initial hash of salt + key is not included in the iteration count.
293293
$algorithm = $this->getAlgorithm($protection->getMswordAlgorithmSid());
294-
$generatedKey = hash($algorithm, base64_decode($this->getSaltHash($protection->getSalt())) . $generatedKey, true);
294+
$generatedKey = hash($algorithm, $protection->getSalt() . $generatedKey, true);
295295

296296
for ($i = 0; $i < $protection->getSpinCount(); $i++) {
297297
$generatedKey = hash($algorithm, $generatedKey . pack("CCCC", $i, $i >> 8, $i >> 16, $i >> 24), true);
@@ -319,17 +319,6 @@ private function getAlgorithm($sid)
319319
return $algorithm;
320320
}
321321

322-
/**
323-
* Get salt hash
324-
*
325-
* @param string $salt
326-
* @return string
327-
*/
328-
private function getSaltHash($salt)
329-
{
330-
return base64_encode(str_pad(substr($salt, 0, 16), 16, '1'));
331-
}
332-
333322
/**
334323
* Build combined key from low-order word and high-order word
335324
*
@@ -372,7 +361,7 @@ private function buildCombinedKey($byteChars)
372361
}
373362

374363
/**
375-
* Simulate behaviour of int32
364+
* Simulate behaviour of (signed) int32
376365
*
377366
* @param int $value
378367
* @return int

0 commit comments

Comments
 (0)