> 백엔드 개발 > PHP 튜토리얼 > OpenSSL을 사용하여 PHP에서 간단한 양방향 암호화를 어떻게 구현할 수 있습니까?

OpenSSL을 사용하여 PHP에서 간단한 양방향 암호화를 어떻게 구현할 수 있습니까?

Barbara Streisand
풀어 주다: 2024-12-13 04:49:13
원래의
308명이 탐색했습니다.

How Can I Implement Simple Two-Way Encryption in PHP Using OpenSSL?

PHP에서 가장 간단한 양방향 암호화

중요 사항:

계속하기 전에 이 기사를 강조하는 것이 중요합니다. 인증되지 않은 암호화에 대한 간단한 이해를 제공하는 것을 목표로 합니다. 강력한 데이터 보호를 위해 항상 업계 표준 인증 암호화 라이브러리 또는 비밀번호 저장을 위한 bcrypt/argon2 사용을 고려하세요.

기본 암호화 방법

PHP 5.4 이상을 사용하는 경우 openssl_* 기능 사용을 고려하세요. 암호화 작업을 위해. 이는 기본적으로 지원되는 강력한 암호화 기능을 제공합니다.

간단한 암호화 및 복호화

OpenSSL의 openssl_encrypt() 및 openssl_decrypt() 기능은 데이터를 암호화하고 복호화하는 접근 가능한 방법을 제공합니다. 권장되는 암호화 알고리즘은 128, 192 또는 256비트 변형의 AES-CTR입니다.

주의: 지원 중단 및 잠재적인 보안 위험으로 인해 mcrypt 사용을 피하세요.

간단한 암호화/복호화 래퍼

암호화 및 복호화를 단순화하려면 암호 해독 프로세스에서는 다음 래퍼 클래스를 활용할 수 있습니다.

class UnsafeCrypto
{
    // Encryption method (CTR mode)
    const METHOD = 'aes-256-ctr';

    /**
     * Encrypts data using the specified key.
     *
     * @param string $message Plaintext message
     * @param string $key Encryption key
     * @param bool $encode Whether to encode the result
     *
     * @return string Ciphertext
     */
    public static function encrypt($message, $key, $encode = false)
    {
        // Generate random IV
        $ivSize = openssl_cipher_iv_length(self::METHOD);
        $iv = openssl_random_pseudo_bytes($ivSize);

        // Encrypt using OpenSSL
        $ciphertext = openssl_encrypt($message, self::METHOD, $key, OPENSSL_RAW_DATA, $iv);

        // Concatenate IV and ciphertext
        if ($encode) {
            return base64_encode($iv . $ciphertext);
        }
        return $iv . $ciphertext;
    }

    /**
     * Decrypts data using the specified key.
     *
     * @param string $message Ciphertext
     * @param string $key Encryption key
     * @param bool $encoded Whether the message is encoded
     *
     * @return string Decrypted message
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }

        // Extract IV and ciphertext
        $ivSize = openssl_cipher_iv_length(self::METHOD);
        $iv = substr($message, 0, $ivSize);
        $ciphertext = substr($message, $ivSize);

        // Decrypt using OpenSSL
        $plaintext = openssl_decrypt($ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $iv);

        return $plaintext;
    }
}
로그인 후 복사

인증된 암호화

위 접근 방식은 암호화만 제공하므로 데이터가 변조에 취약해집니다. 이 문제를 해결하려면 인증된 암호화 체계를 구현하십시오.

class SaferCrypto extends UnsafeCrypto
{
    // MAC algorithm
    const HASH_ALGO = 'sha256';

    /**
     * Encrypts and authenticates data using the specified key.
     *
     * @param string $message Plaintext message
     * @param string $key Encryption key
     * @param bool $encode Whether to encode the result
     *
     * @return string Encrypted and authenticated data
     */
    public static function encrypt($message, $key, $encode = false)
    {
        // Split key into encryption and authentication keys
        list($encKey, $authKey) = self::splitKeys($key);

        // Encrypt using UnsafeCrypto::encrypt
        $ciphertext = parent::encrypt($message, $encKey);

        // Calculate MAC
        $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true);

        // Concatenate MAC and ciphertext
        if ($encode) {
            return base64_encode($mac . $ciphertext);
        }
        return $mac . $ciphertext;
    }

    /**
     * Decrypts and authenticates data using the specified key.
     *
     * @param string $message Encrypted and authenticated data
     * @param string $key Encryption key
     * @param bool $encoded Whether the message is encoded
     *
     * @throws Exception
     *
     * @return string Decrypted message
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        // Split key
        list($encKey, $authKey) = self::splitKeys($key);

        // Decode message if necessary
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }

        // Extract MAC and ciphertext
        $hs = strlen(hash(self::HASH_ALGO, '', true), '8bit');
        $mac = substr($message, 0, $hs);
        $ciphertext = substr($message, $hs);

        // Calculate expected MAC
        $expectedMac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true);

        // Verify MAC
        if (!self::hashEquals($mac, $expectedMac)) {
            throw new Exception('Encryption failure');
        }

        // Decrypt message using UnsafeCrypto::decrypt
        $plaintext = parent::decrypt($ciphertext, $encKey);

        return $plaintext;
    }

    /**
     * Splits a key into two separate keys for encryption and authentication.
     *
     * @param string $masterKey Master key
     *
     * @return string[] Array of encryption and authentication keys
     */
    protected static function splitKeys($masterKey)
    {
        return [
            hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true),
            hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true)
        ];
    }

    /**
     * Compares two strings without leaking timing information
     * (PHP 7+).
     *
     * @param string $a
     * @param string $b
     *
     * @return bool
     */
    protected static function hashEquals($a, $b)
    {
        if (function_exists('hash_equals')) {
            return hash_equals($a, $b);
        }

        $nonce = openssl_random_pseudo_bytes(32);
        return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce);
    }
}
로그인 후 복사

강력한 보안을 위해서는 평판이 좋은 암호화 라이브러리를 활용하는 것이 좋습니다.

위 내용은 OpenSSL을 사용하여 PHP에서 간단한 양방향 암호화를 어떻게 구현할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿