Php 有人知道如何将此代码与MySQL集成吗

Php 有人知道如何将此代码与MySQL集成吗,php,mysql,oop,passwords,Php,Mysql,Oop,Passwords,我让人帮我键入了这段代码,但我不知道如何将其存储在MySQL数据库中并能够对其进行解密。我最初错误地做的是尝试存储密码,然后将其与其他实例进行比较。当我意识到自己在做什么时,我对自己的错误感到震惊。我考虑过存储实例,但这会带来安全风险,因为任何有权访问数据库的人都可以调用$instance->decodePassword($password)。我猜这个脚本并不是专门为MySQL设计的,而我付钱来输入脚本的人也没有响应。我该怎么办?任何帮助都将不胜感激 <?php /** * Passw

我让人帮我键入了这段代码,但我不知道如何将其存储在MySQL数据库中并能够对其进行解密。我最初错误地做的是尝试存储密码,然后将其与其他实例进行比较。当我意识到自己在做什么时,我对自己的错误感到震惊。我考虑过存储实例,但这会带来安全风险,因为任何有权访问数据库的人都可以调用$instance->decodePassword($password)。我猜这个脚本并不是专门为MySQL设计的,而我付钱来输入脚本的人也没有响应。我该怎么办?任何帮助都将不胜感激

<?php

/**
 * Password protection class.
 */
class PasswordCrypt {
    /* Number of rounds to use for PBKDF2 for new setups.
     * May be tweaked up or down because the number of rounds is encoded with the data
     */
    const DEFAULT_PBKDF2_ROUNDS = 10000;

    /* Definition:
     *  Output data = 1 || IV || HMAC_SHA256(K, PROTECT_AES_256_CBC(K, IV, data)) ||  AES_256_CBC(K, IV, data)
     */
    const PROTECT_AES_256_CBC_HMACSHA1 = 1;

    /* Definition:
     *  Uses the PBKDF2 derivation algorithm. The key is encrypted with a protection algorithm..
     *  Output data = 1 || SALT || Rounds (4-byte-integer) || 'Protected' key)
     */
    const TOKEN_PBKDF2_SHA256_AES_256_CBC = 1;

    /* Token which is effectively the key encrypted with the password */
    private $token;

    /* Key used to perform encryption/decryption */
    private $key;

    /* Private constructor that takes the token and key.
     *
     * The token is kept around for storage purposes whereas the key is the main
     * important piece.
     */
    protected function __construct($token, $key) {
        $this->token = $token;
        $this->key = $key;
    }

    /**
     * Create a new instance using a given password.
     *
     * @param $password text string from user
     */
    public static function createWithNewPassword($password) {
        /* Generate the new random key to use */
        $key = PasswordCrypt::generateRandomKey();

        /* Generate the token to store */
        $token = PasswordCrypt::encodeProtectedToken($password, $key);

        /* Setup the instance */
        return new PasswordCrypt($token, $key);
    }


    /**
     * Create a new instance given input token and password.
     *
     * @param $password password associated with the given $token
     * @param $token token for the given user
     *
     * @return null if decoding fails, else value instance that can decrypt/encrypt passwords/etc.
     */
    public static function createFromToken($password, $token) {
        $key = PasswordCrypt::decodeProtectedToken($password, $token);
        if (!$key) {
            return null;
        }

        return new PasswordCrypt($token, $key);
    }

    /**
     * Create a new instance using session data.
     */
    public static function createWithSession() {
        $token = $_SESSION['__pc_token'];
        $sessionKey = $_SESSION['__pc_key'];

        $cookieData = $_COOKIE['__pc_cookie'];
        if (!$token || !$sessionKey || !$cookieData) {
            return null;
        }
        $cookieData = PasswordCrypt::base64url_decode($cookieData);
        $key = PasswordCrypt::decryptData($sessionKey, $cookieData);

        return new PasswordCrypt($token, $key);
    }

    /**
     * Utility function to check if the PHP session state has what is needed for
     * session-based construction.
     */
    public static function hasSessionData() {
        return $_SESSION['__pc_token']
            && $_SESSION['__pc_key']
            && $_COOKIE['__pc_cookie'];
    }

    /**
     * Clear the session state from PHP to prevent re-use (ex: useful for logout)
     */
    public static function clearSessionData() {
        unset($_SESSION['__pc_token']);
        unset($_SESSION['__pc_key']);
        PasswordCrypt::setSessionCookie('__pc_cookie', '');
    }

    /* Utility function to store data in the session and set a cookie to decrypt */
    public function storeSessionKey() {
        $sessionKey = PasswordCrypt::generateRandomKey();
        $cookieData = PasswordCrypt::encryptData($sessionKey, $this->key);

        $_SESSION['__pc_token'] = $this->token;
        $_SESSION['__pc_key'] = $sessionKey;
        PasswordCrypt::setSessionCookie('__pc_cookie', PasswordCrypt::base64url_encode($cookieData));
    }

    /**
     * Utility method to set a session cookie - tweak as appropriate for proper cookie settings for the site.
     */
    private static function setSessionCookie($name, $value) {
        /* Store for session only and assume total path... */
        $secure = false;
        if ($_SERVER["HTTPS"]) {
            $secure = TRUE;
        }
        setcookie($name, $value, 0, "", "", $secure, TRUE);
    }

    /**
     * Method to decode passwords previously encoded.
     *
     * @param $ciphertext raw binary string representing the encrypted password.
     *
     * @return decoded password string as passed in to encodePassword.
     * null may be returned if the data is corrupt, uses a format not supported by
     * this version, or does not match the key.
     */


    public function decodePassword($ciphertext) {
    /* Changed first parameter in decryptData from $this->key to $InsideOutsideKey */
        return PasswordCrypt::decryptData($this->key,$ciphertext);
    }

    /**
     * Method to encode passwords to later be decoded using decodePassword.
     *
     * @param $password text representing the data to protect - may be raw binary.
     *
     * @return encrypted password data in raw binary form. null will be returned if
     * something is critically wrong with the setup - not likely.
     */
    public function encodePassword($password) {
        return PasswordCrypt::encryptData($this->key, $password);
    }

    /**
     * Method to create a new token protected with a new password.
     * Useful for when the user wants to change their password.
     *
     * @param $password new password to encode against.
     *
     * @return token to later be decoded using the provided password.
     */
    public function encodeToken($password) {
        return PasswordCrypt::encodeProtectedToken($password, $this->key);
    }

    /**
     * Method to get the current token as protected by the initial password input.
     *
     * @return token to later be decoded using the initial password at creation.
     */
    public function getToken() {
        return $this->token;
    }
    /**
    *Method to get a random key used by AES-256
    */
    public function getKey() {
        return $this->key;
    }
    /**
     * Utility method to generate a random key as required by AES-256
     */
    private static function generateRandomKey() {
        /* Since using AES 256 CBC - we need 256 bits */
        return openssl_random_pseudo_bytes(256 / 8);
    }

    /* Generate the protected token data */
    private static function encodeProtectedToken($password, $key) {
        $implementation = PasswordCrypt::TOKEN_PBKDF2_SHA256_AES_256_CBC;
        switch ($implementation) {
        case PasswordCrypt::TOKEN_PBKDF2_SHA256_AES_256_CBC:
            /* Generate fresh salt to prevent rainbow table attacks */
            $salt = openssl_random_pseudo_bytes(16);
            /* Use the defaults configured */
            $iterations = PasswordCrypt::DEFAULT_PBKDF2_ROUNDS;
            /* Derive the key using PBKDF2 with SHA256 per the token key generation scheme */
            $passwordDerivedKey = PasswordCrypt::pbkdf2("SHA256", $password, $salt, $iterations, 256 / 8, true);
            /* Encrypt the 'real' key data using the password-based key */
            $data = PasswordCrypt::encryptData($passwordDerivedKey, $key);
            return pack("Ca16La*", $implementation, $salt, $iterations, $data);
        default:
            return null;
        }
    }

    /* Decode the protected token data */
    private static function decodeProtectedToken($password, $tokenData) {
        list(,$implementation) = unpack("C", $tokenData);
        switch ($implementation) {
        case PasswordCrypt::TOKEN_PBKDF2_SHA256_AES_256_CBC:
            /* Extract the salt encoded in the protection data */
            $salt = substr($tokenData, 1, 16);
            /* Extract the number of iterations used for this data */
            list(,$iterations) = unpack("L", substr($tokenData, 1 + 16, 4));
            /* Extract the encrypted key data */
            $encrypted = substr($tokenData, 1 + 16 + 4);
            /* Derive the key using PBKDF2 with SHA256 per the token key generation scheme */
            $passwordDerivedKey = PasswordCrypt::pbkdf2("SHA256", $password, $salt, $iterations, 256 / 8, true);
            /* Decrypt the key data using the derived key */
            return PasswordCrypt::decryptData($passwordDerivedKey, $encrypted);
        default:
            return null;
        }
    }

    /* Protect data using a given input key */
    private static function encryptData($key, $plaintext) {
        $implementation = PasswordCrypt::PROTECT_AES_256_CBC_HMACSHA1;
        switch ($implementation) {
        case PasswordCrypt::PROTECT_AES_256_CBC_HMACSHA1:
            /* Some PHP versions to not have OPENSSL_RAW_DATA option and instead use a boolean for raw, so handle it */
            $options = defined("OPENSSL_RAW_DATA") ? OPENSSL_RAW_DATA : true;
            /* 16-byte IV */
            $iv = openssl_random_pseudo_bytes(16);

            /* Encrypt the data first */
            $encrypted = openssl_encrypt($plaintext, "aes-256-cbc", bin2hex($key), $options, $iv);
            /* Generate an HMAC over the data to make sure final output matches */
            $hmac = hash_hmac("sha1", $encrypted, $key, TRUE);
            /* HMAC should be 160 bits long - 20 bytes */
            return pack("Ca16a20A*", $implementation, $iv, $hmac, $encrypted);
        default:
            return null;
        }
    }

    /* Decoded protected data with a given key */
    private static function decryptData($key, $ciphertext) {
        list(,$implementation) = unpack("C", $ciphertext);
        switch ($implementation) {
        case PasswordCrypt::PROTECT_AES_256_CBC_HMACSHA1:
            $iv = substr($ciphertext, 1, 16);
            $included_hmac = substr($ciphertext, 1 + 16, 20);
            $encrypted = substr($ciphertext, 1 + 16 + 20);
            /* Verify the HMAC */
            $hmac = hash_hmac("sha1", $encrypted, $key, TRUE);
            if ($hmac != $included_hmac) {
                /* HMAC did not match, bad key or corrupt data */
                return null;
            }
            /* Some PHP versions to not have OPENSSL_RAW_DATA option and instead use a boolean for raw, so handle it */
            $options = defined("OPENSSL_RAW_DATA") ? OPENSSL_RAW_DATA : true;
            $decrypted = openssl_decrypt($encrypted, "aes-256-cbc", bin2hex($key), $options, $iv);
            return $decrypted;
        default:
            return null;
        }
    }

    /*
     * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
     * $algorithm - The hash algorithm to use. Recommended: SHA256
     * $password - The password.
     * $salt - A salt that is unique to the password.
     * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
     * $key_length - The length of the derived key in bytes.
     * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
     * Returns: A $key_length-byte key derived from the password and salt.
     *
     * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
     *
     * This implementation of PBKDF2 was originally created by https://defuse.ca
     * With improvements by http://www.variations-of-shadow.com
     */
    private static function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false) {
        $algorithm = strtolower($algorithm);
        if(!in_array($algorithm, hash_algos(), true)) {
            trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);
        }
        if($count <= 0 || $key_length <= 0) {
            trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);
        }
        /* If we have a version of PHP with the native hash_pbkdf2 - use that! */
        if (function_exists("hash_pbkdf2")) {
            // The output length is in NIBBLES (4-bits) if $raw_output is false!
            if (!$raw_output) {
                $key_length = $key_length * 2;
            }
            return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output);
        }
        $hash_length = strlen(hash($algorithm, "", true));
        $block_count = ceil($key_length / $hash_length);
        $output = "";
        for($i = 1; $i <= $block_count; $i++) {
            // $i encoded as 4 bytes, big endian.
            $last = $salt . pack("N", $i);
            // first iteration
            $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
            // perform the other $count - 1 iterations
            for ($j = 1; $j < $count; $j++) {
                $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
            }
            $output .= $xorsum;
        }
        if($raw_output) {
            return substr($output, 0, $key_length);
        } else {
            return bin2hex(substr($output, 0, $key_length));
        }
    }
    private static function base64url_encode($data) {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }

    private static function base64url_decode($data) {
        return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
    }
}

?>

添加这个对我来说很有效。现在,我可以从数据库中检索到的令牌创建一个新实例。我很惊讶你们都没想到这一点

/****
    Beginning of added mysqli method
    *****/
    public static function createWithNewMysqli($fetched_token,$fetched_key)
    {
        return new PasswordCrypt($fetched_token, $fetched_key);
    }
    /****
    End of added mysqli method

    ****/

如果您只是在登录,请查看您的php是否有可用的password_hash()函数。如果是,请查看如何使用它及其配套的密码\u verify()。如果不是,则有一个兼容的github库,即bcrypt密码哈希库