Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F726813
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Jan 6, 12:47 AM
Size
6 KB
Mime Type
text/x-diff
Expires
Wed, Jan 8, 12:47 AM (1 d, 13 h ago)
Engine
blob
Format
Raw Data
Handle
536904
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.2.x/core/kernel/security/SecurityEncrypter.php
===================================================================
--- branches/5.2.x/core/kernel/security/SecurityEncrypter.php (revision 16770)
+++ branches/5.2.x/core/kernel/security/SecurityEncrypter.php (revision 16771)
@@ -1,228 +1,238 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2018 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class SecurityEncrypter extends kBase
{
const HASHING_ALGORITHM = 'sha256';
const HASHING_KEY_LENGTH = 32;
const ENCRYPTION_METHOD = 'aes-128-cbc'; // Or 'aes-256-cbc'.
const ENCRYPTION_KEY_LENGTH = 16; // Or 32.
/**
* The HMAC key.
*
* @var string
*/
protected $hmacKey;
/**
* The encryption key.
*
* @var string
*/
protected $encryptionKey;
/**
* SecurityEncrypter constructor.
*/
public function __construct()
{
parent::__construct();
$vars = kUtil::getSystemConfig()->getData();
// In the config data is encoded stored to avoid corruption.
$this->hmacKey = base64_decode($vars['SecurityHmacKey']);
// Equivalent of "hex2bin" for PHP < 5.4.
$this->encryptionKey = pack('H*', $vars['SecurityEncryptionKey']);
}
/**
+ * Remove security-related info from serialized object version.
+ *
+ * @return array
+ */
+ public function __sleep()
+ {
+ return array('Prefix', 'Special', 'prefixSpecial');
+ }
+
+ /**
* Creates signature.
*
* @param string $string String.
* @param boolean $raw_output Return raw signature version.
* @param string|null $key_override Override key.
*
* @return string
*/
public function createSignature($string, $raw_output = false, $key_override = null)
{
return hash_hmac(self::HASHING_ALGORITHM, $string, $this->_getHmacKey($key_override), $raw_output);
}
/**
* Returns HMAC key.
*
* @param string|null $key_override Key override.
*
* @return string
* @throws InvalidArgumentException When HMAC key is empty.
*/
private function _getHmacKey($key_override = null)
{
$key = $this->doGetHmacKey($key_override);
if ( empty($key) ) {
throw new InvalidArgumentException('The HMAC key is empty.');
}
if ( mb_strlen($key, '8bit') === self::HASHING_KEY_LENGTH ) {
return $key;
}
return $this->deriveKey($key, self::HASHING_KEY_LENGTH);
}
/**
* Returns HMAC key.
*
* @param string|null $key_override Key override.
*
* @return string
*/
protected function doGetHmacKey($key_override = null)
{
return isset($key_override) ? $key_override : $this->hmacKey;
}
/**
* Returns encryption key.
*
* @param string|null $key_override Key override.
*
* @return string
* @throws InvalidArgumentException When encryption key is empty.
*/
private function _getEncryptionKey($key_override = null)
{
$key = $this->doGetEncryptionKey($key_override);
if ( empty($key) ) {
throw new InvalidArgumentException('The encryption key is empty.');
}
if ( mb_strlen($key, '8bit') === self::ENCRYPTION_KEY_LENGTH ) {
return $key;
}
return $this->deriveKey($key, self::ENCRYPTION_KEY_LENGTH);
}
/**
* Returns encryption key.
*
* @param string|null $key_override Key override.
*
* @return string
*/
protected function doGetEncryptionKey($key_override = null)
{
return isset($key_override) ? $key_override : $this->encryptionKey;
}
/**
* Derives given key.
*
* @param string $key Key.
* @param integer $length Length.
*
* @return string
*/
final public function deriveKey($key, $length)
{
$salt = SecurityGenerator::generateBytes(16, true);
return hash_pbkdf2(self::HASHING_ALGORITHM, $key, $salt, 80000, $length, true);
}
/**
* Encrypts a plain text.
*
* @param string $plaintext Plain text.
* @param string|null $key_override Key override.
*
* @return string
*/
final public function encrypt($plaintext, $key_override = null)
{
$iv_size = openssl_cipher_iv_length(self::ENCRYPTION_METHOD);
$iv = openssl_random_pseudo_bytes($iv_size);
$ciphertext = openssl_encrypt(
$plaintext,
self::ENCRYPTION_METHOD,
$this->_getEncryptionKey($key_override),
OPENSSL_RAW_DATA,
$iv
);
// Note: We cover the IV in our HMAC.
$hmac = $this->createSignature($iv . $ciphertext, true);
return base64_encode($hmac . $iv . $ciphertext);
}
/**
* Decrypts a cipher text.
*
* @param string $ciphertext Cipher text.
* @param string|null $key_override Key override.
*
* @return string|false
* @throws LogicException When signature verification has failed.
*/
final public function decrypt($ciphertext, $key_override = null)
{
$iv_size = openssl_cipher_iv_length(self::ENCRYPTION_METHOD);
$decoded = base64_decode($ciphertext);
$hmac = mb_substr($decoded, 0, self::HASHING_KEY_LENGTH, '8bit');
$iv = mb_substr($decoded, self::HASHING_KEY_LENGTH, $iv_size, '8bit');
$ciphertext = mb_substr($decoded, self::HASHING_KEY_LENGTH + $iv_size, null, '8bit');
$calculated = $this->createSignature($iv . $ciphertext, true);
if ( !hash_equals($hmac, $calculated) ) {
throw new LogicException('Signature verification of ciphertext failed.');
}
return openssl_decrypt(
$ciphertext,
self::ENCRYPTION_METHOD,
$this->_getEncryptionKey($key_override),
OPENSSL_RAW_DATA,
$iv
);
}
/**
* Determines if used cipher is available.
*
* @return boolean
*/
final public function cipherAvailable()
{
return in_array(self::ENCRYPTION_METHOD, openssl_get_cipher_methods(), true);
}
}
Event Timeline
Log In to Comment