سؤال

I'm using RIJNDAEL to encrypt/decrypt passwords and some other strings, but it doesn't work.

This is my encrypt/decrypt function:

function secreto($accion,$clave,$palabra) {
//SETEO DATA EN 0 PORSIACA
$data = 0;
//INICIALIZO EL VECTOR
$iv = md5($clave);
//SI TENGO QUE ENCRIPTAR
if($accion == 'encripta') {
    $data = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $clave, $palabra, MCRYPT_MODE_CBC, $iv);
    $data = base64_encode($data);
} elseif($accion == 'decripta') {
    $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $clave, base64_decode($palabra), MCRYPT_MODE_CBC, $iv);
    $data = rtrim($data, "");
}
return $data;
}

Here is the relevant part I'm using to log in a user:

session_start();
if(isset($_SESSION['usuario']) && isset($_SESSION['domadmin']) && isset($_SESSION['superadmin'])) {
    $usuario = $_SESSION['usuario'];
    $tipoadmin = $_SESSION['tipoadmin'];
    if(isset($_GET['p'])) { $p = $_GET['p']; } else {  $p = "resumen"; }
    echo TPcabecera();
    echo TPmenu($p);
    echo TPcentral($p);
    echo TPpie();
} else {
    if(isset($_POST['usuario']) && isset($_POST['password'])) {
        $post_usr = mysqli_real_escape_string(sqls("mail"), $_POST['usuario']);
        $post_pwd = mysqli_real_escape_string(sqls("mail"), $_POST['password']);
        $data = sql("mail", "SELECT email,superadmin,domadmin,syspass FROM users WHERE email = '".$post_usr."'");
        if(mysqli_num_rows($data) == 0) {
            echo TPlogin();
        } else {
            $row = mysqli_fetch_assoc($data);
            $pass = secreto('decripta',$passsalt,$row['syspass']);
            if($post_pwd == $pass) {
                $usuario = $row['email'];
                if($row['superadmin'] == '1') { $tipoadmin = 'superadmin'; } elseif($_SESSION['domadmin'] != '0') { $tipoadmin = $_SESSION['domadmin']; } else { $tipoadmin = '0'; }
                if(isset($_GET['p'])) { $p = $_GET['p']; } else {  $p = "resumen"; }
                echo TPcabecera();
                echo TPmenu($p);
                echo TPcentral($p);
                echo TPpie();
            } else {
                echo TPlogin();
            }
        }
    } else {
        echo TPlogin();
    }
}

If I echo $pass and $post_pwd, they are exactly the same, yet the if($post_pwd == $pass) doesn't validate... am I using encryption in the wrong way?

هل كانت مفيدة؟

المحلول

Your secreto function should "work". With your login code I don't see where you initialize $passsalt. So either there is a part of your code that you aren't showing, or $passsalt isn't actually set.

Your encryption is insecure though:

  1. You shouldn't be using a password as your encryption key. Human passwords typically don't have enough entropy.

  2. You are somewhat exposing your key by using a hashed version of it as your IV.

  3. An IV is meant to protect your key by "randomizing" the first encrypted block. This ensures that even when you encrypt the same text with the same key, the output will be different. Because you use a constant IV, you are not getting any benefit from it.

If possible your key should be random, using a character range of 0 - 255. Your IV must always be different when you encrypt. The IV can be public, so you can even store it with the encrypted text.

You should also avoid storing the encryption key in the database along with the encrypted data.

If you are encrypting passwords, I would use a one-way hash designed for passwords instead, like scrypt or bcrypt.

نصائح أخرى

This is something I want to add:

Organize you code with Separation of concerns in mind, so perform each task in small separate steps. This will help you write clearer code and keep it DRY.

I recommend putting the encode / decode parts into separate functions. For example:

<?php
// Encrypt function
function mc_encrypt($encrypt, $mc_key)
{
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
    $passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
    $encode = base64_encode($passcrypt);
    return $encode;
}

// Decrypt function
function mc_decrypt($decrypt, $mc_key)
{
    $decoded = base64_decode($decrypt);
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv));
    return $decrypted;
}

This way you can call them directly.

For the authentication, have a look at this:
http://ulogin.sourceforge.net/

Also check this out:
Highly Secure Data Encryption & Decryption Made Easy with PHP, MCrypt, Rijndael-256, and CBC

Good luck.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top