【问题标题】:PHP: How can I encrypt data in one file and then decrypt it in another file?PHP:如何加密一个文件中的数据,然后在另一个文件中解密?
【发布时间】:2020-07-23 05:30:28
【问题描述】:

我正在尝试制作一个人们可以聊天的程序,并且我想加密正在发送的消息。为此我有 2 个脚本,一个是 sendtext.php,另一个是 getchat.php。

所以我的问题是如何加密在一个文件中发送的文本,然后解密将在另一个文件中发送回的消息。

到目前为止,我的加密工作正常,但我不知道如何在其他文件中解密。 此外,如果您知道一种更安全的方法,我们将不胜感激。

sendtext.php

    $username = $_POST["name"];
    $text = $_POST["message"];

    $key = openssl_random_pseudo_bytes(32, $cstrong);
    $cipher = "aes-128-gcm";

    if (in_array($cipher, openssl_get_cipher_methods()))
    {
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt($text, $cipher, $key, $options=0, $iv, $tag);

        echo "Encrytped: " . $ciphertext;

        //store $cipher, $iv, and $tag for decryption later
        //$original_text = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
        //echo $original_text."\n";
    }

    //Add text to the table
    $inserttextquery = "INSERT INTO ".$username." (username, message) 
                        VALUES ('$username', '$ciphertext');";
    mysqli_query($con, $inserttextquery) or die("#: send text failed");

getchat.php

$username = $_POST["name"];

    $sql = "SELECT username, message FROM ".$username."";
    $result = $con->query($sql);

    if ($result->num_rows > 0)
    {
        // output data of each row
        while($row = $result->fetch_assoc()) {
            echo $row["username"] . "\t" . $row["message"] . "\t";
        }
    } 

【问题讨论】:

  • 这段代码很容易受到 SQL 注入攻击,如果还没有被黑客入侵,将被黑客入侵。加密是您最不必担心的事情。
  • 每个用户都有一张桌子?您不应该像这样构建数据库。很快就会一团糟。有一个users 表并将所有用户存储在那里。然后是其他表中的 userid(一个自动递增的列)。
  • @user3783243 你能详细说明一下吗?我有一个包含所有用户的表(具有 id 自动增量和所有用户)。是的,我为每个用户提供了一张表,用于将他们的聊天记录存储在另一个数据库(称为 userchats)中。我怎样才能让它变得更好?
  • 有一个users 表有userid, username, hashedpass, etcuserid 自动增量,这样你就不会遇到竞争案例/冲突。然后你可以做类似select ... from messages where userid = ? 这样的事情,你会得到一个用户的所有消息。您当前的方式将数据分散在数千个表中......索引文本也比整数更昂贵。

标签: php mysql encryption


【解决方案1】:

我前段时间写了这个加密/解密类:

<?php
class Cryptography
{
    private static $secret_key = 'gsdgsg423b523b5432bjbjm24vbjn2hv';
    const CIPHER_16 = 'AES-128-CBC';
    const CIPHER_32 = 'AES-256-CBC';
    public static function encrypt($str, $cl = 32)
    {
        return static::encyptedDecypted('encrypt', $str, $cl);
    }
    public static function decrypt($str, $cl = 32)
    {
        return static::encyptedDecypted('decrypt', $str, $cl);
    }
    public static function encyptedDecypted($action, $str, $cl)
    {
        $cl = (int) $cl;
        if ($cl === 16) {
            $cipher = static::CIPHER_16;
            $length = 16;
        } elseif ($cl === 32) {
            $cipher = static::CIPHER_32;
            $length = 32;
        } else {
            throw new Exception('Error Processing Request', 1);
        }
        $iv = $iv = substr(hash('sha256', static:: $secret_key), 0, 16);
        $key = hash('sha512', static::$secret_key);
        if ($action == 'encrypt') {
            $output = openssl_encrypt($str, $cipher, $key, 0, $iv);
            $output = base64_encode($output);
            $output = static::securesalts($length).$output.static::securesalts($length);
        } elseif ($action == 'decrypt') {
            $str = $text = substr($str, $length, -$length);
            $output = openssl_decrypt(base64_decode($str), $cipher, $key, 0, $iv);
        }
        return $output;
    }
    private static function securesalts($length)
    {
        if (is_int($length) && $length >= 5) {
            $chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));
            $stringlength = count($chars); //Used Count because its array now
            $randomString = '';
            for ($i = 0; $i < $length; $i++) {
                $randomString .= $chars[rand(0, $stringlength - 1)];
            }
            return $randomString;
        } else {
            return false;
        }
    }
}

像这样使用它:

$str = "Simple String";

//for encryption
$encrypted = Cryptography::encrypt($str);

//for decryption
$decrypted = Cryptography::decrypt($encrypted);

别忘了更改$secret_key ;)

【讨论】:

  • 非常感谢!我试试看 :) 它对 SQL 注入攻击开放吗?
  • @NorAlexanian 这与 SQL 无关。它只是加密/解密一个字符串。与 SQL 交互的方式是使您面临注入的原因。不要在 SQL 中放变量,参数化和绑定。
  • @NorAlexanian 这个类与 SQL 无关,你用它来解密/加密一个字符串。其他人已经指出你在 SQL 方面做错了什么,所以我想我应该回答你真正的问题。如果您认为我的回答解决了它,请将其标记为正确!否则,这是您的选择。
  • 是的,它成功了,谢谢!是的,我研究了 sql 问题并将修复它
猜你喜欢
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
  • 2013-05-01
  • 2017-05-07
相关资源
最近更新 更多