use confkey for encrypting instead of fragile user password

Cette révision appartient à :
Daniel Seifert 2018-10-22 12:10:43 +02:00
Parent 96057b594a
révision 58fb0cb803
6 fichiers modifiés avec 16 ajouts et 58 suppressions

Voir le fichier

@ -73,7 +73,8 @@ class d3user_totp extends AdminDetailsController
/** @var d3_totp_user $oUser */
$oUser = oxNew(User::class);
if (false == $oUser->d3CheckPasswordPass($this->getEditObjectId(), $pwd)) {
$oUser->load($this->getEditObjectId());
if (false == $oUser->isSamePassword($pwd)) {
$oException = oxNew(StandardException::class, 'D3_TOTP_ERROR_PWDONTPASS');
throw $oException;
}
@ -87,7 +88,7 @@ class d3user_totp extends AdminDetailsController
$seed = Registry::getRequest()->getRequestEscapedParameter("secret");
$otp = Registry::getRequest()->getRequestEscapedParameter("otp");
$oTotp->saveSecret($seed, $pwd);
$oTotp->saveSecret($seed);
$oTotp->assign($aParams);
$oTotp->verify($otp, $seed);
$oTotp->setId();

Voir le fichier

@ -20,6 +20,7 @@ use BaconQrCode\Writer;
use D3\ModCfg\Application\Model\d3database;
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
use Doctrine\DBAL\DBALException;
use Exception;
use OTPHP\TOTP;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\DatabaseProvider;
@ -104,10 +105,9 @@ class d3totp extends BaseModel
public function getSavedSecret()
{
$seed_enc = $this->getFieldData('seed');
$sPwd = Registry::getSession()->getVariable('pwdTransmit');
if ($seed_enc && $sPwd) {
$seed = $this->decrypt($seed_enc, $sPwd);
if ($seed_enc) {
$seed = $this->decrypt($seed_enc);
if ($seed) {
return $seed;
}
@ -171,13 +171,12 @@ class d3totp extends BaseModel
/**
* @param $seed
* @param $key
*/
public function saveSecret($seed, $key)
public function saveSecret($seed)
{
$this->assign(
array(
'seed' => $this->encrypt($seed, $key)
'seed' => $this->encrypt($seed)
)
);
}
@ -200,14 +199,12 @@ class d3totp extends BaseModel
}
/**
* $key should have previously been generated in a cryptographically secure manner, e.g. via openssl_random_pseudo_bytes
*
* @param $plaintext
* @param $key
* @return string
*/
public function encrypt($plaintext, $key)
public function encrypt($plaintext)
{
$key = Registry::getConfig()->getConfigParam('sConfigKey');
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
@ -216,14 +213,12 @@ class d3totp extends BaseModel
}
/**
* $key should have previously been generated in a cryptographically secure manner, e.g. via openssl_random_pseudo_bytes
*
* @param $ciphertext
* @param $key
* @return bool|string
*/
public function decrypt($ciphertext, $key)
public function decrypt($ciphertext)
{
$key = Registry::getConfig()->getConfigParam('sConfigKey');
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);

Voir le fichier

@ -32,7 +32,7 @@ $aLang = [
'D3_TOTP_SECRET' => 'QR-Code kann nicht gescannt werden?',
'D3_TOTP_SECRET_HELP' => 'Setzen Sie keine App ein, die den QR-Code scannen kann, können Sie diese Zeichenkette auch in Ihr Authentisierungstool kopieren. Stellen Sie bitte zusätzlich die Passwortlänge auf 6 Zeichen und das Zeitinterval auf 30 Sekunden ein.',
'D3_TOTP_CURRPWD' => 'Anmeldepasswort des Benutzerkontos',
'D3_TOTP_CURRPWD_HELP' => 'Die Zeichenkette wird verschlüsselt im Shop abgelegt. Zum Verschlüsseln wird das Passwort des ausgewählten Kundenkontos benötigt. Zugleich stellt dies sicher, dass nur Berechtigte Änderungen an diesen Einstellungen vornehmen dürfen.',
'D3_TOTP_CURRPWD_HELP' => 'Dies stellt sicher, dass nur Berechtigte Änderungen an diesen Einstellungen vornehmen dürfen.',
'D3_TOTP_CURROTP' => 'Bestätigung mit Einmalpasswort',
'D3_TOTP_CURROTP_HELP' => 'Haben Sie dieses Kundenkonto in Ihrer Authentisierungs-App registriert, generieren Sie damit ein Einmalpasswort, tragen Sie es hier ein und senden das Formular direkt darauf hin ab.',

Voir le fichier

@ -32,7 +32,7 @@ $aLang = [
'D3_TOTP_SECRET' => 'Can not scan QR code?',
'D3_TOTP_SECRET_HELP' => 'If you do not use an app that can scan the QR code, you can also copy this string into your authentication tool. Please also set the password length to 6 characters and the time interval to 30 seconds.',
'D3_TOTP_CURRPWD' => 'Login password of the user account',
'D3_TOTP_CURRPWD_HELP' => 'The character string is stored encrypted in the shop. To encrypt, the password of the selected customer account is required. Concurrently, this ensures that only authorized users can make changes to these settings.',
'D3_TOTP_CURRPWD_HELP' => 'This ensures that only authorized users can make changes to these settings.',
'D3_TOTP_CURROTP' => 'Confirmation with one-time password',
'D3_TOTP_CURROTP_HELP' => 'If you have registered this customer account in your authentication app, you generate a one-time password, enter it here and send the form out immediately.',

Voir le fichier

@ -41,7 +41,6 @@ class d3_totp_LoginController extends d3_totp_LoginController_parent
if ($auth
&& $totp->isActive()
&& false == Registry::getSession()->getVariable(d3totp::TOTP_SESSION_VARNAME)
&& Registry::getSession()->hasVariable('pwdTransmit')
) {
// set auth as secured parameter;
Registry::getSession()->setVariable("auth", $auth);
@ -63,10 +62,6 @@ class d3_totp_LoginController extends d3_totp_LoginController_parent
$totp = oxNew(d3totp::class);
$totp->loadByUserId(Registry::getSession()->getVariable("auth"));
if (Registry::getRequest()->getRequestParameter('pwd')) {
Registry::getSession()->setVariable('pwdTransmit', Registry::getRequest()->getRequestParameter('pwd'));
}
$return = 'login';
try {
@ -74,7 +69,6 @@ class d3_totp_LoginController extends d3_totp_LoginController_parent
$return = parent::checklogin();
} elseif ($this->hasValidTotp($sTotp, $totp)) {
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, $sTotp);
Registry::getSession()->deleteVariable('pwdTransmit');
$return = "admin_start";
}
} catch (d3totp_wrongOtpException $oEx) {

Voir le fichier

@ -17,9 +17,11 @@ namespace D3\Totp\Modules\Application\Model;
use D3\Totp\Application\Model\d3totp;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Application\Controller\ForgotPasswordController;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Application\Controller\Admin\UserMain;
class d3_totp_user extends d3_totp_user_parent
{
@ -33,40 +35,6 @@ class d3_totp_user extends d3_totp_user_parent
return $return;
}
/**
* @param $sUserId
* @param $sPassword
* @return bool
* @throws DatabaseConnectionException
*/
public function d3CheckPasswordPass($sUserId, $sPassword)
{
return (bool) DatabaseProvider::getDb(DatabaseProvider::FETCH_MODE_ASSOC)->getOne(
$this->d3GetPasswordCheckQuery($sUserId, $sPassword)
);
}
/**
* @param $sUserId
* @param $sPassword
* @return string
* @throws DatabaseConnectionException
*/
public function d3GetPasswordCheckQuery($sUserId, $sPassword)
{
$oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$sUserSelect = "oxuser.oxid = " . $oDb->quote($sUserId);
$sSalt = $oDb->getOne("SELECT `oxpasssalt` FROM `oxuser` WHERE " . $sUserSelect);
$sPassSelect = " oxuser.oxpassword = " . $oDb->quote($this->encodePassword($sPassword, $sSalt));
$sSelect = "select `oxid` from oxuser where 1 and {$sPassSelect} and {$sUserSelect} ";
return $sSelect;
}
/**
* @return d3totp
* @throws DatabaseConnectionException