Skip to content

Commit 615707e

Browse files
committed
Use mb_* throughout crypto classes.
The str* functions can easily do the wrong thing when the string functions are overloaded. By using the mbstring functions we can ensure stable byte counting and byte slicing. Refs #6139
1 parent b5761c5 commit 615707e

File tree

3 files changed

+17
-16
lines changed

3 files changed

+17
-16
lines changed

src/Utility/Crypto/Mcrypt.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ public static function rijndael($text, $key, $operation)
4040
$mode = MCRYPT_MODE_CBC;
4141
$ivSize = mcrypt_get_iv_size($algorithm, $mode);
4242

43-
$cryptKey = substr($key, 0, 32);
43+
$cryptKey = mb_substr($key, 0, 32, '8bit');
4444

4545
if ($operation === 'encrypt') {
4646
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
4747
return $iv . '$$' . mcrypt_encrypt($algorithm, $cryptKey, $text, $mode, $iv);
4848
}
49-
$iv = substr($text, 0, $ivSize);
50-
$text = substr($text, $ivSize + 2);
49+
$iv = mb_substr($text, 0, $ivSize, '8bit');
50+
$text = mb_substr($text, $ivSize + 2, null, '8bit');
5151
return rtrim(mcrypt_decrypt($algorithm, $cryptKey, $text, $mode, $iv), "\0");
5252
}
5353

@@ -72,7 +72,7 @@ public static function encrypt($plain, $key)
7272
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
7373

7474
// Pad out plain to make it AES compatible.
75-
$pad = ($ivSize - (strlen($plain) % $ivSize));
75+
$pad = ($ivSize - (mb_strlen($plain, '8bit') % $ivSize));
7676
$plain .= str_repeat(chr($pad), $pad);
7777

7878
return $iv . mcrypt_encrypt($algorithm, $key, $plain, $mode, $iv);
@@ -92,18 +92,19 @@ public static function decrypt($cipher, $key)
9292
$mode = MCRYPT_MODE_CBC;
9393
$ivSize = mcrypt_get_iv_size($algorithm, $mode);
9494

95-
$iv = substr($cipher, 0, $ivSize);
96-
$cipher = substr($cipher, $ivSize);
95+
$iv = mb_substr($cipher, 0, $ivSize, '8bit');
96+
$cipher = mb_substr($cipher, $ivSize, null, '8bit');
9797
$plain = mcrypt_decrypt($algorithm, $key, $cipher, $mode, $iv);
9898

9999
// Remove PKCS#7 padding or Null bytes
100100
// Newer values will be PKCS#7 padded, while old
101101
// mcrypt values will be null byte padded.
102-
$padChar = substr($plain, -1);
102+
$padChar = mb_substr($plain, -1, null, '8bit');
103103
if ($padChar === "\0") {
104104
return trim($plain, "\0");
105105
}
106106
$padLen = ord($padChar);
107-
return substr($plain, 0, -$padLen);
107+
$result = mb_substr($plain, 0, -$padLen, '8bit');
108+
return $result === '' ? false : $result;
108109
}
109110
}

src/Utility/Crypto/OpenSsl.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ public static function decrypt($cipher, $key)
7777
$method = 'AES-256-CBC';
7878
$ivSize = openssl_cipher_iv_length($method);
7979

80-
$iv = substr($cipher, 0, $ivSize);
80+
$iv = mb_substr($cipher, 0, $ivSize, '8bit');
8181

82-
$cipher = substr($cipher, $ivSize);
82+
$cipher = mb_substr($cipher, $ivSize, null, '8bit');
8383
return openssl_decrypt($cipher, $method, $key, true, $iv);
8484
}
8585
}

src/Utility/Security.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public static function rijndael($text, $key, $operation)
146146
if (empty($operation) || !in_array($operation, ['encrypt', 'decrypt'])) {
147147
throw new InvalidArgumentException('You must specify the operation for Security::rijndael(), either encrypt or decrypt');
148148
}
149-
if (strlen($key) < 32) {
149+
if (mb_strlen($key, '8bit') < 32) {
150150
throw new InvalidArgumentException('You must use a key larger than 32 bytes for Security::rijndael()');
151151
}
152152
$crypto = static::engine();
@@ -174,7 +174,7 @@ public static function encrypt($plain, $key, $hmacSalt = null)
174174
$hmacSalt = static::$_salt;
175175
}
176176
// Generate the encryption and hmac key.
177-
$key = substr(hash('sha256', $key . $hmacSalt), 0, 32);
177+
$key = mb_substr(hash('sha256', $key . $hmacSalt), 0, 32, '8bit');
178178

179179
$crypto = static::engine();
180180
$ciphertext = $crypto->encrypt($plain, $key);
@@ -192,7 +192,7 @@ public static function encrypt($plain, $key, $hmacSalt = null)
192192
*/
193193
protected static function _checkKey($key, $method)
194194
{
195-
if (strlen($key) < 32) {
195+
if (mb_strlen($key, '8bit') < 32) {
196196
throw new InvalidArgumentException(
197197
sprintf('Invalid key for %s, key must be at least 256 bits (32 bytes) long.', $method)
198198
);
@@ -219,12 +219,12 @@ public static function decrypt($cipher, $key, $hmacSalt = null)
219219
}
220220

221221
// Generate the encryption and hmac key.
222-
$key = substr(hash('sha256', $key . $hmacSalt), 0, 32);
222+
$key = mb_substr(hash('sha256', $key . $hmacSalt), 0, 32, '8bit');
223223

224224
// Split out hmac for comparison
225225
$macSize = 64;
226-
$hmac = substr($cipher, 0, $macSize);
227-
$cipher = substr($cipher, $macSize);
226+
$hmac = mb_substr($cipher, 0, $macSize, '8bit');
227+
$cipher = mb_substr($cipher, $macSize, null, '8bit');
228228

229229
$compareHmac = hash_hmac('sha256', $cipher, $key);
230230
if (!static::_constantEquals($hmac, $compareHmac)) {

0 commit comments

Comments
 (0)