donglu7998 2013-05-11 11:17
浏览 133

使用加密功能加密mysql数据库中的安全密码

I want to encrypt password to prevent SQL injection and other attacks and I used an encryption function in PHP, but I don't know how to use it to encrypt passwords.

I want each password in the user table to be encrypted so i can connect to the database and use a query but it doesn't work.

Can anyone help me please?

ecnription.php

<?php
require_once('include/connect.php');

if(isset($_SESSION['user_id']))
{
    $id= $_SESSION['user_id'];


}
$sql = mysql_query("SELECT password FROM user WHERE user_id= '$id'")or die(mysql_error());
while($row = mysql_fetch_array($sql))
{
    $enc_pass= $row['password'];

}

error_reporting(0);

class Encryption
{
    const CYPHER = MCRYPT_RIJNDAEL_256;
    const MODE   = MCRYPT_MODE_CBC;
    const KEY    = 'somesecretphrase';

    public function encrypt($plaintext)
    {
        $td = mcrypt_module_open(self::CYPHER, '', self::MODE, '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, self::KEY, $iv);
        $crypttext = mcrypt_generic($td, $plaintext);
        mcrypt_generic_deinit($td);
        return base64_encode($iv.$crypttext);
    }

    public function decrypt($crypttext)
    {
        $crypttext = base64_decode($crypttext);
        $plaintext = '';
        $td        = mcrypt_module_open(self::CYPHER, '', self::MODE, '');
        $ivsize    = mcrypt_enc_get_iv_size($td);
        $iv        = substr($crypttext, 0, $ivsize);
        $crypttext = substr($crypttext, $ivsize);
        if ($iv)
        {
            mcrypt_generic_init($td, self::KEY, $iv);
            $plaintext = mdecrypt_generic($td, $crypttext);
        }
        return trim($plaintext);
    }
}


$encrypted_string = Encryption::encrypt($enc_pass); 
$decrypted_string = Encryption::decrypt($encrypted_string);

echo $encrypted_string . "<br>" . PHP_EOL;
var_dump($id);
echo $decrypted_string . "<br>" . PHP_EOL;
  • 写回答

1条回答 默认 最新

  • dtpoius74857 2013-05-11 11:47
    关注

    In fact password encryption has nothing in common with mysql injection. You should (MUST!) do theese things separately.

    Password encryption (or in this case hashing) will make it unable for possible hacker who gained access to your databse to use your users passwords. Hash functions are one way - you can create hash from password, but no password from hash. The only way to get password from hash is to hash every possible combination of chars and check whether this hash equals to this in db. Most uf users uses simple md5() or sha256() functions in php. In fact it works, but the problem with those functions is their simplicity. The were created to calculate check-sums of files, so they must have been fast. Thats why it makes it easier to brute-force. To avoid being brute-forced you can:

    a) Add 'salt' and keep using md5 / sha256. Salt is a random string added to user password before hashing. You must create additional column in your databse, near 'password' for example. Each user should get random, at least 32 chars long salt. The 'password' field is created using md5(salt . users_password). If you want to check the password on login - get the password and salt fields from databse, get users password from post and compare: md5(salt . user_password_from_post) to 'password' in databse. Even if users password is short it becomes long and complex because of the salt. To crack / brute force all 8-chars password you need only ~80^8 hashes, but to brute force salted 8-chars password you need ~80^40 which is 80^32 times longer.

    b) use blowfish algorithm http://php.net/manual/en/function.crypt.php The blowfish was created from the beggining to crypt passwords. You also have to use salt, but you also can specify 'cost' parameter which indicates how complex would be the hash. More complex = more cpu usage on every password check but also more safety. Password secured with blowfish, 16-bytes salt and at least 10 cost are said to be safe.

    To avoid being sql-injected you should escape every parameter passed to your query. mysql_real_escape_string() becomes your friend.

    $Query = sprintf("SELECT UserId, Password, Salt FROM Users WHERE Username='%s'", mysql_real_escape_string($_POST['Username']));
    mysql_query($Query);
    

    If the

    $_POST['Username'] = "'; DROP TABLE Users; --"
    

    your query without escaping would become:

    "SELECT UserId, Password, Salt FROM Users WHERE Username=''; DROP TABLE Users; --'
    

    by this query any user can destroy your database without any problem. With mysql_real_escape_string, query would look loke:

    "SELECT UserId, Password, Salt FROM Users WHERE Username='\'; DROP TABLE Users; --'
    

    Now your database is safe.

    The complete code for checking password (you should have username(128), password(32), salt(32) in DB):

    function CheckPassword($Username, $Password)
    {
        list($Count) = mysql_fetch_array(mysql_query(sprintf("SELECT COUNT(*) FROM Users WHERE Username='%s'", mysql_real_escape_string($Username))));
        if(!$Count)
            return false; //No such user
        list($Password_Db, $Salt) = mysql_fetch_array(mysql_query(sprintf("SELECT Password, Salt FROM Users WHERE Username='%s'", mysql_real_escape_string($Username))));
        if(md5($Salt . $Password) == $Password_Db)
            return true;
        return false;
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)