Improved encrypt/decrypt methods with option to choose the cipher_method (#1489719)

pull/297/head
Aleksander Machniak 9 years ago
parent fdbb1c95ea
commit e4c66080a8

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Improved encrypt/decrypt methods with option to choose the cipher_method (#1489719)
- Make optional adding of standard signature separator - sig_separator (#1487768)
- Optimize folder_size() on Cyrus IMAP by using special folder annotation (#1490514)
- Make optional hidding of folders with name starting with a dot - imap_skip_hidden_folders (#1490468)

@ -446,11 +446,16 @@ $config['referer_check'] = false;
// Possible values: sameorigin|deny. Set to false in order to disable sending them
$config['x_frame_options'] = 'sameorigin';
// this key is used to encrypt the users imap password which is stored
// in the session record (and the client cookie if remember password is enabled).
// please provide a string of exactly 24 chars.
// This key is used for encrypting purposes, like storing of imap password
// in the session. For historical reasons it's called DES_key, but it's used
// with any configured cipher_method (see below).
$config['des_key'] = 'rcmail-!24ByteDESkey*Str';
// Encryption algorithm. You can use any method supported by openssl.
// Default is set for backward compatibility to DES-EDE3-CBC,
// but you can choose e.g. AES-256-CBC which we consider a better choice.
$config['cipher_method'] = 'DES-EDE3-CBC';
// Automatically add this domain to user names for login
// Only for IMAP servers that require full e-mail addresses for login
// Specify an array with 'host' => 'domain' values to support multiple hosts

@ -128,8 +128,7 @@ echo $input_deskey->show($RCI->getprop('des_key'));
?>
<div>This key is used to encrypt the users imap password before storing in the session record</div>
<p class="hint">It's a random generated string to ensure that every installation has its own key.
If you enter it manually please provide a string of exactly 24 chars.</p>
<p class="hint">It's a random generated string to ensure that every installation has its own key.</p>
</dd>
<dt class="propname">ip_check</dt>

@ -810,26 +810,22 @@ class rcube
}
/**
* Encrypt using 3DES
* Encrypt a string
*
* @param string $clear Clear text input
* @param string $key Encryption key to retrieve from the configuration, defaults to 'des_key'
* @param boolean $base64 Whether or not to base64_encode() the result before returning
*
* @return string encrypted text
* @return string Encrypted text
*/
public function encrypt($clear, $key = 'des_key', $base64 = true)
{
if (!$clear) {
if (!is_string($clear) || !strlen($clear)) {
return '';
}
// Add a single canary byte to the end of the clear text, which
// will help find out how much of padding will need to be removed
// upon decryption; see http://php.net/mcrypt_generic#68082.
$clear = pack("a*H2", $clear, "80");
$ckey = $this->config->get_crypto_key($key);
$method = 'DES-EDE3-CBC';
$method = $this->config->get_crypto_method();
$opts = defined('OPENSSL_RAW_DATA') ? OPENSSL_RAW_DATA : true;
$iv = rcube_utils::random_bytes(openssl_cipher_iv_length($method), true);
$cipher = $iv . openssl_encrypt($clear, $method, $ckey, $opts, $iv);
@ -838,13 +834,13 @@ class rcube
}
/**
* Decrypt 3DES-encrypted string
* Decrypt a string
*
* @param string $cipher Encrypted text
* @param string $key Encryption key to retrieve from the configuration, defaults to 'des_key'
* @param boolean $base64 Whether or not input is base64-encoded
*
* @return string decrypted text
* @return string Decrypted text
*/
public function decrypt($cipher, $key = 'des_key', $base64 = true)
{
@ -852,10 +848,9 @@ class rcube
return '';
}
$cipher = $base64 ? base64_decode($cipher) : $cipher;
$ckey = $this->config->get_crypto_key($key);
$method = 'DES-EDE3-CBC';
$cipher = $base64 ? base64_decode($cipher) : $cipher;
$ckey = $this->config->get_crypto_key($key);
$method = $this->config->get_crypto_method();
$opts = defined('OPENSSL_RAW_DATA') ? OPENSSL_RAW_DATA : true;
$iv_size = openssl_cipher_iv_length($method);
$iv = substr($cipher, 0, $iv_size);
@ -868,10 +863,6 @@ class rcube
$cipher = substr($cipher, $iv_size);
$clear = openssl_decrypt($cipher, $method, $ckey, $opts, $iv);
// Trim PHP's padding and the canary byte; see note in
// rcube::encrypt() and http://php.net/mcrypt_generic#68082
$clear = substr(rtrim($clear, "\0"), 0, -1);
return $clear;
}

@ -505,7 +505,7 @@ class rcube_config
public function get_crypto_key($key)
{
// Bomb out if the requested key does not exist
if (!array_key_exists($key, $this->prop)) {
if (!array_key_exists($key, $this->prop) || empty($this->prop[$key])) {
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@ -513,18 +513,23 @@ class rcube_config
), true, true);
}
$key = $this->prop[$key];
return $this->prop[$key];
}
// Bomb out if the configured key is not exactly 24 bytes long
if (strlen($key) != 24) {
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Configured crypto key '$key' is not exactly 24 bytes long"
), true, true);
/**
* Return configured crypto method.
*
* @return string Crypto method
*/
public function get_crypto_method()
{
$method = $this->get('cipher_method');
if (empty($method)) {
$method = 'DES-EDE3-CBC';
}
return $key;
return $method;
}
/**

Loading…
Cancel
Save