158 lines
4.1 KiB
PHP
158 lines
4.1 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @copyright Copyright (c)2018 Ryan Demmer
|
|
* @license GNU General Public License version 3, or later
|
|
*
|
|
* @since 2.7
|
|
*/
|
|
// Protection against direct access
|
|
defined('JPATH_PLATFORM') or die();
|
|
|
|
use Defuse\Crypto\Key;
|
|
use Defuse\Crypto\Encoding;
|
|
use Defuse\Crypto\Crypto;
|
|
|
|
/**
|
|
* Implements encrypted settings handling features.
|
|
*/
|
|
class JceEncryptHelper
|
|
{
|
|
protected static function generateKey()
|
|
{
|
|
$keyObject = Key::createNewRandomKey();
|
|
$keyAscii = $keyObject->saveToAsciiSafeString();
|
|
|
|
$keyData = Encoding::binToHex($keyAscii);
|
|
|
|
$filecontents = "<?php defined('WF_EDITOR') or die(); define('WF_SERVERKEY', '$keyData'); ?>";
|
|
$filename = JPATH_ADMINISTRATOR . '/components/com_jce/serverkey.php';
|
|
|
|
file_put_contents($filename, $filecontents);
|
|
|
|
return Key::loadFromAsciiSafeString($keyAscii);
|
|
}
|
|
|
|
/**
|
|
* Gets the configured server key, automatically loading the server key storage file
|
|
* if required.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function getKey($legacy = false)
|
|
{
|
|
if (!defined('WF_SERVERKEY')) {
|
|
$filename = JPATH_ADMINISTRATOR . '/components/com_jce/serverkey.php';
|
|
|
|
if (is_file($filename)) {
|
|
include_once($filename);
|
|
}
|
|
}
|
|
|
|
if (defined('WF_SERVERKEY')) {
|
|
// return key as string
|
|
if ($legacy) {
|
|
$key = base64_decode(WF_SERVERKEY);
|
|
return $key;
|
|
}
|
|
|
|
try {
|
|
$keyAscii = Encoding::hexToBin(WF_SERVERKEY);
|
|
$key = Key::loadFromAsciiSafeString($keyAscii);
|
|
} catch(Defuse\Crypto\Exception\BadFormatException $ex) {
|
|
return "";
|
|
}
|
|
|
|
return $key;
|
|
}
|
|
|
|
return self::generateKey();
|
|
}
|
|
|
|
/**
|
|
* Encrypts the settings using the automatically detected preferred algorithm.
|
|
*
|
|
* @param $settingsINI string The raw settings INI string
|
|
*
|
|
* @return string The encrypted data to store in the database
|
|
*/
|
|
public static function encrypt($data, $key = null)
|
|
{
|
|
// Do we have a non-empty key to begin with?
|
|
if (empty($key)) {
|
|
$key = self::getKey();
|
|
}
|
|
|
|
if (empty($key)) {
|
|
return $data;
|
|
}
|
|
|
|
$encrypted = Crypto::encrypt($data, $key);
|
|
|
|
// base64encode
|
|
$encoded = base64_encode($encrypted);
|
|
|
|
// add marker
|
|
$data = '###DEFUSE###' . $encoded;
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Decrypts the encrypted settings and returns the plaintext INI string.
|
|
*
|
|
* @param $encrypted string The encrypted data
|
|
*
|
|
* @return string The decrypted data
|
|
*/
|
|
public static function decrypt($encrypted, $key = null)
|
|
{
|
|
$mode = substr($encrypted, 0, 12);
|
|
|
|
if ($mode == '###AES128###' || $mode == '###CTR128###') {
|
|
require_once(__DIR__ . '/encrypt/aes.php');
|
|
|
|
$encrypted = substr($encrypted, 12);
|
|
|
|
$key = self::getKey(true);
|
|
|
|
switch ($mode) {
|
|
case '###AES128###':
|
|
$encrypted = base64_decode($encrypted);
|
|
$decrypted = @WFUtilEncrypt::AESDecryptCBC($encrypted, $key, 128);
|
|
break;
|
|
|
|
case '###CTR128###':
|
|
$decrypted = @WFUtilEncrypt::AESDecryptCtr($encrypted, $key, 128);
|
|
break;
|
|
}
|
|
|
|
return rtrim($decrypted, "\0");
|
|
}
|
|
|
|
if ($mode == '###DEFUSE###') {
|
|
$key = self::getKey();
|
|
|
|
if (empty($key)) {
|
|
return $encrypted;
|
|
}
|
|
|
|
//get encrypted string without marker
|
|
$encrypted = substr($encrypted, 12);
|
|
|
|
// base64decode
|
|
$decoded = base64_decode($encrypted);
|
|
|
|
try {
|
|
$decrypted = Crypto::decrypt($decoded, $key);
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
|
|
return $encrypted;
|
|
}
|
|
|
|
return rtrim($decrypted, "\0");
|
|
}
|
|
|
|
return $encrypted;
|
|
}
|
|
}
|