Use AES-256-GCM and SHA256

This commit is contained in:
Sebastian Meyer 2021-01-19 14:08:09 +01:00
parent 8f506cded0
commit 6c8b905981
6 changed files with 64 additions and 34 deletions

View File

@ -34,6 +34,24 @@ class Helper
*/
public static $extKey = 'dlf';
/**
* This holds the cipher algorithm
* @see openssl_get_cipher_methods() for options
*
* @var string
* @access protected
*/
protected static $cipherAlgorithm = 'aes-256-gcm';
/**
* This holds the hash algorithm
* @see openssl_get_md_methods() for options
*
* @var string
* @access protected
*/
protected static $hashAlgorithm = 'sha256';
/**
* The locallang array for flash messages
*
@ -143,31 +161,35 @@ class Helper
* @access public
*
* @param string $encrypted: The encrypted value to decrypt
* @param string $hash: The control hash for decrypting
*
* @return mixed The decrypted value or null on error
* @return mixed The decrypted value or false on error
*/
public static function decrypt($encrypted, $hash)
public static function decrypt($encrypted)
{
if (
empty($encrypted)
|| empty($hash)
!in_array(self::$cipherAlgorithm, openssl_get_cipher_methods(true))
|| !in_array(self::$hashAlgorithm, openssl_get_md_methods(true))
) {
self::devLog('Invalid parameters given for decryption', DEVLOG_SEVERITY_ERROR);
return;
self::devLog('OpenSSL library doesn\'t support cipher and/or hash algorithm', DEVLOG_SEVERITY_ERROR);
return false;
}
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
self::devLog('No encryption key set in TYPO3 configuration', DEVLOG_SEVERITY_ERROR);
return;
return false;
}
$iv = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, openssl_cipher_iv_length('BF-CFB'));
$decrypted = openssl_decrypt($encrypted, 'BF-CFB', substr($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 0, 56), 0, $iv);
$salt = substr($hash, 0, 10);
$hashed = $salt . substr(sha1($salt . $decrypted), -10);
if ($hashed !== $hash) {
self::devLog('Invalid hash "' . $hash . '" given for decryption', DEVLOG_SEVERITY_WARNING);
return;
if (
empty($encrypted)
|| strlen($encrypted) < openssl_cipher_iv_length(self::$cipherAlgorithm)
) {
self::devLog('Invalid parameters given for decryption', DEVLOG_SEVERITY_ERROR);
return false;
}
// Split initialisation vector and encrypted data.
$iv = substr($encrypted, 0, openssl_cipher_iv_length(self::$cipherAlgorithm));
$data = substr($encrypted, openssl_cipher_iv_length(self::$cipherAlgorithm));
$key = openssl_digest($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], self::$hashAlgorithm, true);
// Decrypt data.
$decrypted = openssl_decrypt($data, self::$cipherAlgorithm, $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
@ -221,19 +243,31 @@ class Helper
*
* @param string $string: The string to encrypt
*
* @return array Array with encrypted string and control hash
* @return string Encrypted string or false on error
*/
public static function encrypt($string)
{
if (
!in_array(self::$cipherAlgorithm, openssl_get_cipher_methods(true))
|| !in_array(self::$hashAlgorithm, openssl_get_md_methods(true))
) {
self::devLog('OpenSSL library doesn\'t support cipher and/or hash algorithm', DEVLOG_SEVERITY_ERROR);
return false;
}
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
self::devLog('No encryption key set in TYPO3 configuration', DEVLOG_SEVERITY_ERROR);
return;
return false;
}
$iv = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, openssl_cipher_iv_length('BF-CFB'));
$encrypted = openssl_encrypt($string, 'BF-CFB', substr($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 0, 56), 0, $iv);
$salt = substr(md5(uniqid(rand(), true)), 0, 10);
$hash = $salt . substr(sha1($salt . $string), -10);
return ['encrypted' => $encrypted, 'hash' => $hash];
// Generate random initialisation vector.
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(self::$cipherAlgorithm));
$key = openssl_digest($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], self::$hashAlgorithm, true);
// Encrypt data.
$encrypted = openssl_encrypt($string, self::$cipherAlgorithm, $key, OPENSSL_RAW_DATA, $iv);
// Merge initialisation vector and encrypted data.
if ($encrypted !== false) {
$encrypted = $iv . $encrypted;
}
return $encrypted;
}
/**

View File

@ -44,12 +44,11 @@ class SearchInDocument
// Get input parameters and decrypt core name.
$parameters = $request->getParsedBody();
$encrypted = (string) $parameters['encrypted'];
$hashed = (string) $parameters['hashed'];
$count = intval($parameters['start']);
if (empty($encrypted) || empty($hashed)) {
if (empty($encrypted)) {
throw new \InvalidArgumentException('No valid parameter passed!', 1580585079);
}
$core = Helper::decrypt($encrypted, $hashed);
$core = Helper::decrypt($encrypted);
// Perform Solr query.
$solr = Solr::getInstance($core);
if ($solr->ready) {

View File

@ -42,11 +42,10 @@ class SearchSuggest
// Get input parameters and decrypt core name.
$parameters = $request->getParsedBody();
$encrypted = (string) $parameters['encrypted'];
$hashed = (string) $parameters['hashed'];
if (empty($encrypted) || empty($hashed)) {
if (empty($encrypted)) {
throw new \InvalidArgumentException('No valid parameter passed!', 1580585079);
}
$core = Helper::decrypt($encrypted, $hashed);
$core = Helper::decrypt($encrypted);
// Perform Solr query.
$solr = Solr::getInstance($core);
if ($solr->ready) {

View File

@ -150,8 +150,8 @@ class Search extends \Kitodo\Dlf\Common\AbstractPlugin
$name = Helper::encrypt($name);
}
// Add encrypted fields to search form.
if (is_array($name)) {
return '<input type="hidden" name="' . $this->prefixId . '[encrypted]" value="' . $name['encrypted'] . '" /><input type="hidden" name="' . $this->prefixId . '[hashed]" value="' . $name['hash'] . '" />';
if ($name !== false) {
return '<input type="hidden" name="' . $this->prefixId . '[encrypted]" value="' . $name . '" />';
} else {
return '';
}

View File

@ -108,8 +108,7 @@ class SearchInDocumentTool extends \Kitodo\Dlf\Common\AbstractPlugin
'###LABEL_PAGE###' => htmlspecialchars($this->pi_getLL('label.logicalPage')),
'###LABEL_NORESULT###' => htmlspecialchars($this->pi_getLL('label.noresult')),
'###CURRENT_DOCUMENT###' => $this->doc->uid,
'###SOLR_ENCRYPTED###' => isset($encryptedSolr['encrypted']) ? $encryptedSolr['encrypted'] : '',
'###SOLR_HASH###' => isset($encryptedSolr['hash']) ? $encryptedSolr['hash'] : '',
'###SOLR_ENCRYPTED###' => $encryptedSolr ?: '',
];
$content .= $this->templateService->substituteMarkerArray($this->template, $markerArray);
@ -134,7 +133,7 @@ class SearchInDocumentTool extends \Kitodo\Dlf\Common\AbstractPlugin
*
* @access protected
*
* @return array with encrypted core name and hash
* @return string with encrypted core name
*/
protected function getEncryptedCoreName()
{

View File

@ -17,7 +17,6 @@
<input type="hidden" name="tx_dlf[start]" value="0" />
<input type="hidden" name="tx_dlf[id]" value="###CURRENT_DOCUMENT###" />
<input type="hidden" name="tx_dlf[encrypted]" value="###SOLR_ENCRYPTED###" />
<input type="hidden" name="tx_dlf[hashed]" value="###SOLR_HASH###" />
</div>
</form>
<div id="tx-dlf-search-in-document-loading" style="display: none;">###LABEL_LOADING###...</div>