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'; 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 * The locallang array for flash messages
* *
@ -143,31 +161,35 @@ class Helper
* @access public * @access public
* *
* @param string $encrypted: The encrypted value to decrypt * @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 ( if (
empty($encrypted) !in_array(self::$cipherAlgorithm, openssl_get_cipher_methods(true))
|| empty($hash) || !in_array(self::$hashAlgorithm, openssl_get_md_methods(true))
) { ) {
self::devLog('Invalid parameters given for decryption', DEVLOG_SEVERITY_ERROR); self::devLog('OpenSSL library doesn\'t support cipher and/or hash algorithm', DEVLOG_SEVERITY_ERROR);
return; return false;
} }
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) { if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
self::devLog('No encryption key set in TYPO3 configuration', DEVLOG_SEVERITY_ERROR); 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')); if (
$decrypted = openssl_decrypt($encrypted, 'BF-CFB', substr($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 0, 56), 0, $iv); empty($encrypted)
$salt = substr($hash, 0, 10); || strlen($encrypted) < openssl_cipher_iv_length(self::$cipherAlgorithm)
$hashed = $salt . substr(sha1($salt . $decrypted), -10); ) {
if ($hashed !== $hash) { self::devLog('Invalid parameters given for decryption', DEVLOG_SEVERITY_ERROR);
self::devLog('Invalid hash "' . $hash . '" given for decryption', DEVLOG_SEVERITY_WARNING); return false;
return;
} }
// 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; return $decrypted;
} }
@ -221,19 +243,31 @@ class Helper
* *
* @param string $string: The string to encrypt * @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) 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'])) { if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
self::devLog('No encryption key set in TYPO3 configuration', DEVLOG_SEVERITY_ERROR); 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')); // Generate random initialisation vector.
$encrypted = openssl_encrypt($string, 'BF-CFB', substr($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 0, 56), 0, $iv); $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(self::$cipherAlgorithm));
$salt = substr(md5(uniqid(rand(), true)), 0, 10); $key = openssl_digest($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], self::$hashAlgorithm, true);
$hash = $salt . substr(sha1($salt . $string), -10); // Encrypt data.
return ['encrypted' => $encrypted, 'hash' => $hash]; $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. // Get input parameters and decrypt core name.
$parameters = $request->getParsedBody(); $parameters = $request->getParsedBody();
$encrypted = (string) $parameters['encrypted']; $encrypted = (string) $parameters['encrypted'];
$hashed = (string) $parameters['hashed'];
$count = intval($parameters['start']); $count = intval($parameters['start']);
if (empty($encrypted) || empty($hashed)) { if (empty($encrypted)) {
throw new \InvalidArgumentException('No valid parameter passed!', 1580585079); throw new \InvalidArgumentException('No valid parameter passed!', 1580585079);
} }
$core = Helper::decrypt($encrypted, $hashed); $core = Helper::decrypt($encrypted);
// Perform Solr query. // Perform Solr query.
$solr = Solr::getInstance($core); $solr = Solr::getInstance($core);
if ($solr->ready) { if ($solr->ready) {

View File

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

View File

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

View File

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

View File

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