source

PHP 문자열을 암호화 및 해독하려면 어떻게 해야 합니까?

factcode 2022. 9. 18. 09:48
반응형

PHP 문자열을 암호화 및 해독하려면 어떻게 해야 합니까?

내 말은:

Original String + Salt or Key --> Encrypted String
Encrypted String + Salt or Key --> Decrypted (Original String)

예를 들어 다음과 같습니다.

"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"
  • PHP에서는 어떻게 할 수 있을까요?

를 사용하려고 했지만 소용없었다.

추가 작업을 수행하기 전에 암호화와 인증의 차이암호화뿐만 아니라 인증된 암호화를 원하는 이유를 파악하십시오.

인증된 암호화를 구현하려면 암호화 후 MAC을 암호화해야 합니다.암호화와 인증의 순서는 매우 중요합니다!이 질문에 대한 기존 답변 중 하나가 이 오류를 범했습니다. 많은 암호화 라이브러리가 PHP로 작성되었습니다.

자체 암호화 구현을 피하고 암호화 전문가가 작성하고 검토하는 안전한 라이브러리를 사용해야 합니다.

업데이트: PHP 7.2는 Libsodium을 제공하게 되었습니다!최상의 보안을 위해 PHP 7.2 이상을 사용하도록 시스템을 업데이트하고 이 답변의 libsodium 조언만 따르십시오.

PECL에 액세스 할 수 있는 경우는 libsodium(또는 PECL을 사용하지 않는 libsodium을 필요로 하는 경우는 sodium_compat)을 사용합니다.그렇지 않은 경우는...
디퓨즈/php 암호화를 사용합니다.암호화를 직접 실행하지 마십시오.

위에 링크된 두 라이브러리 모두 인증된 암호화를 자신의 라이브러리에 쉽고 쉽게 구현할 수 있습니다.

인터넷상의 모든 암호화 전문가의 통념에 반해, 독자적인 암호화 라이브러리를 작성해 전개하고 싶은 경우는, 다음의 순서를 실행할 필요가 있습니다.

암호화:

  1. CTR 모드에서 AES를 사용하여 암호화합니다.GCM 을 사용할 수도 있습니다(이를 통해 별도의 MAC 를 사용할 필요가 없어집니다.또한 ChaCha20 및 Salsa20(립소듐 제공)은 스트림 암호이므로 특별한 모드가 필요하지 않습니다.
  2. 위의 [GCM]를 선택하지 않으면 HMAC-SHA-256(또는 스트림 암호의 경우 Poly1305)을 사용하여 암호문을 인증해야 합니다.대부분의 libsodium API는 이를 수행합니다.MAC는 암호문뿐만 아니라 IV도 커버해야 합니다.

복호화:

  1. Poly1305 또는 GCM을 사용하지 않는 한 암호문의 MAC을 다시 계산하여 를 사용하여 전송된 MAC과 비교합니다.실패했을 경우는, 중단해 주세요.
  2. 메시지를 복호화합니다.

기타 설계상 고려사항:

  1. 절대 아무것도 압축하지 마세요.암호문은 압축할 수 없습니다.암호화 전에 평문을 압축하면 정보가 유출될 수 있습니다(예를 들어, TLS의 CRIME 및 BREACH).
  2. 사용하세요.mb_strlen() ★★★★★★★★★★★★★★★★★」mb_substr()'8bit': " " " " " 를 방지합니다.mbstring.func_overload★★★★★★★★★★★★★★★★★★.
  3. IV는 CSPRNG를 사용하여 생성해야 합니다.mcrypt_create_iv(), 사용하지 마십시오!
  4. AED 구조를 사용하지 않는 한 항상 암호화한 다음 MAC을 암호화하십시오!
  5. bin2hex(),base64_encode()캐시 타이밍을 통해 암호화 키에 대한 정보가 유출될 수 있습니다.능하가

여기에 제시된 조언에 따르더라도 암호화에 많은 것이 잘못될 수 있습니다.항상 암호화 전문가가 구현을 검토하도록 하십시오.지역 대학의 암호학과 학생과 개인적인 친구가 될 수 없을 경우 언제든지 암호 스택 교환 포럼을 통해 조언을 구할 수 있습니다.

구현에 대한 전문적인 분석이 필요한 경우 언제든지 평판이 좋은 보안 컨설턴트 팀을 고용하여 PHP 암호화 코드(공개: my exposer)를 검토할 수 있습니다.

중요:암호화를 사용하지 않는 경우

암호를 암호화하지 마십시오.대신 다음 비밀번호 해시 알고리즘 중 하나를 사용하여 해시합니다.

비밀번호 저장에는 범용 해시함수(MD5, SHA256)를 사용하지 마십시오.

URL 매개 변수를 암호화하지 않습니다.그것은 그 일에 적합하지 않은 도구이다.

립소듐을 사용한PHP 문자열 암호화 예시

PHP < 7.2 를 사용하고 있는 경우나 libsodium 이 설치되어 있지 않은 경우 sodium_compatium 을 사용하여 같은 결과를 얻을 수 있습니다(단, 속도는 느리지만).

<?php
declare(strict_types=1);

/**
 * Encrypt a message
 * 
 * @param string $message - message to encrypt
 * @param string $key - encryption key
 * @return string
 * @throws RangeException
 */
function safeEncrypt(string $message, string $key): string
{
    if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
        throw new RangeException('Key is not the correct size (must be 32 bytes).');
    }
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    
    $cipher = base64_encode(
        $nonce.
        sodium_crypto_secretbox(
            $message,
            $nonce,
            $key
        )
    );
    sodium_memzero($message);
    sodium_memzero($key);
    return $cipher;
}

/**
 * Decrypt a message
 * 
 * @param string $encrypted - message encrypted with safeEncrypt()
 * @param string $key - encryption key
 * @return string
 * @throws Exception
 */
function safeDecrypt(string $encrypted, string $key): string
{   
    $decoded = base64_decode($encrypted);
    $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    
    $plain = sodium_crypto_secretbox_open(
        $ciphertext,
        $nonce,
        $key
    );
    if (!is_string($plain)) {
        throw new Exception('Invalid MAC');
    }
    sodium_memzero($ciphertext);
    sodium_memzero($key);
    return $plain;
}

테스트하려면:

<?php
// This refers to the previous code block.
require "safeCrypto.php"; 

// Do this once then store it somehow:
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
$message = 'We are all living in a yellow submarine';

$ciphertext = safeEncrypt($message, $key);
$plaintext = safeDecrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);

할로겐산염 - 립소듐을 쉽게 사용

제가 하고 있는 프로젝트 중 하나는 Halite라고 불리는 암호화 라이브러리입니다.이 라이브러리는 립소듐을 보다 쉽고 직관적으로 만드는 것을 목표로 하고 있습니다.

<?php
use \ParagonIE\Halite\KeyFactory;
use \ParagonIE\Halite\Symmetric\Crypto as SymmetricCrypto;

// Generate a new random symmetric-key encryption key. You're going to want to store this:
$key = new KeyFactory::generateEncryptionKey();
// To save your encryption key:
KeyFactory::save($key, '/path/to/secret.key');
// To load it again:
$loadedkey = KeyFactory::loadEncryptionKey('/path/to/secret.key');

$message = 'We are all living in a yellow submarine';
$ciphertext = SymmetricCrypto::encrypt($message, $key);
$plaintext = SymmetricCrypto::decrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);

기본 암호는 모두 립소듐에 의해 처리된다.

디퓨즈/php 암호화 예시

<?php
/**
 * This requires https://github.com/defuse/php-encryption
 * php composer.phar require defuse/php-encryption
 */

use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;

require "vendor/autoload.php";

// Do this once then store it somehow:
$key = Key::createNewRandomKey();

$message = 'We are all living in a yellow submarine';

$ciphertext = Crypto::encrypt($message, $key);
$plaintext = Crypto::decrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);

주의:Crypto::encrypt()열여섯 살

암호화 키 관리

만약 당신이 "비밀번호"를 사용하고 싶다면, 지금 당장 멈추세요.인간의 기억에 남는 패스워드가 아닌 임의의 128비트 암호화 키가 필요합니다.

다음과 같이 장기간 사용하기 위해 암호화 키를 저장할 수 있습니다.

$storeMe = bin2hex($key);

필요에 따라 다음과 같이 검색할 수 있습니다.

$key = hex2bin($storeMe);

임의의 패스워드를 키로서(또는 키를 취득하기 위해서) 보관하는 것이 아니라 랜덤으로 생성된 키를 장기간 보관하는 것을 강력히 추천합니다.

Defuse 라이브러리를 사용하는 경우:

"하지만 비밀번호를 꼭 사용하고 싶어요."

좋지 않은 생각이지만, 좋아, 안전하게 하는 방법이 있어.

먼저 랜덤 키를 생성하여 상수에 저장합니다.

/**
 * Replace this with your own salt! 
 * Use bin2hex() then add \x before every 2 hex characters, like so:
 */
define('MY_PBKDF2_SALT', "\x2d\xb7\x68\x1a\x28\x15\xbe\x06\x33\xa0\x7e\x0e\x8f\x79\xd5\xdf");

추가 작업이 필요하므로 이 상수를 키로 사용하여 마음의 고통을 줄일 수 있습니다.

그런 다음 PBKDF2를 사용하여 패스워드로 직접 암호화하지 않고 패스워드에서 적절한 암호화 키를 가져옵니다.

/**
 * Get an AES key from a static password and a secret salt
 * 
 * @param string $password Your weak password here
 * @param int $keysize Number of bytes in encryption key
 */
function getKeyFromPassword($password, $keysize = 16)
{
    return hash_pbkdf2(
        'sha256',
        $password,
        MY_PBKDF2_SALT,
        100000, // Number of iterations
        $keysize,
        true
    );
}

16글자의 비밀번호만 사용하지 마십시오.암호화 키가 깨집니다.

파티에 늦었지만, 올바른 방법을 찾다가 이 페이지를 보게 되었습니다. 구글 검색 수익률 상위 중 하나였기 때문에 이 게시물을 쓸 당시(2017년 시작)에는 이 문제에 대한 제 견해를 공유하고자 합니다..1부터 PHP 7.1.0까지mcrypt_decrypt ★★★★★★★★★★★★★★★★★」mcrypt_encrypt권장되지 않으므로 향후 증명 코드를 빌드할 때 openssl_pairs openssl_pairs를 사용해야 합니다.

다음과 같은 작업을 수행할 수 있습니다.

$string_to_encrypt="Test";
$password="password";
$encrypted_string=openssl_encrypt($string_to_encrypt,"AES-128-ECB",$password);
$decrypted_string=openssl_decrypt($encrypted_string,"AES-128-ECB",$password);

중요:이것은 안전하지 않은 ECB 모드를 사용합니다.암호화 엔지니어링을 수강하지 않고 간단한 솔루션을 원하는 경우 직접 작성하지 말고 라이브러리를 사용하십시오.

보안 요구에 따라 다른 치퍼 방법도 사용할 수 있습니다.사용 가능한 치퍼 메서드에 대해서는 openssl_get_cipher_methods 함수를 참조하십시오.

하지 말아야 할 일


이 답변은 ECB를 사용합니다.ECB는 암호화 모드가 아니라 구성 요소일 뿐입니다.이 답변에서 설명한 바와 같이 ECB를 사용해도 실제로는 스트링이 안전하게 암호화되지 않습니다.코드에 ECB를 사용하지 마십시오.좋은 해결책은 Scott의 답변을 참조하십시오.

내가 알아서 하지사실 구글에서 답을 찾아서 수정했어요.그러나 결과는 완전히 불확실하다.

<?php
define("ENCRYPTION_KEY", "!@#$%^&*");
$string = "This is the original data string!";

echo $encrypted = encrypt($string, ENCRYPTION_KEY);
echo "<br />";
echo $decrypted = decrypt($encrypted, ENCRYPTION_KEY);

/**
 * Returns an encrypted & utf8-encoded
 */
function encrypt($pure_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
    return $encrypted_string;
}

/**
 * Returns decrypted original string
 */
function decrypt($encrypted_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB, $iv);
    return $decrypted_string;
}
?>

Laravel 프레임워크의 경우

Laravel 프레임워크를 사용하는 경우 내부 함수로 암호화 및 복호화가 더 쉬워집니다.

$string = 'Some text to be encrypted';
$encrypted = \Illuminate\Support\Facades\Crypt::encrypt($string);
$decrypted_string = \Illuminate\Support\Facades\Crypt::decrypt($encrypted);

var_dump($string);
var_dump($encrypted);
var_dump($decrypted_string);

주의: config/app.php 파일의 key 옵션에서 16, 24 또는 32 문자의 랜덤 문자열을 설정하십시오.그렇지 않으면 암호화된 값은 안전하지 않습니다.

갱신필

PHP 7 지원 버전.PHP OpenSSL 라이브러리의 openssl_encrypt 함수를 사용합니다.

class Openssl_EncryptDecrypt {
    function encrypt ($pure_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext_raw = openssl_encrypt($pure_string, $cipher, $encryption_key, $options, $iv);
        $hmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        return $iv.$hmac.$ciphertext_raw;
    }
    function decrypt ($encrypted_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = substr($encrypted_string, 0, $ivlen);
        $hmac = substr($encrypted_string, $ivlen, $sha2len);
        $ciphertext_raw = substr($encrypted_string, $ivlen+$sha2len);
        $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $encryption_key, $options, $iv);
        $calcmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        if(function_exists('hash_equals')) {
            if (hash_equals($hmac, $calcmac)) return $original_plaintext;
        } else {
            if ($this->hash_equals_custom($hmac, $calcmac)) return $original_plaintext;
        }
    }
    /**
     * (Optional)
     * hash_equals() function polyfilling.
     * PHP 5.6+ timing attack safe comparison
     */
    function hash_equals_custom($knownString, $userString) {
        if (function_exists('mb_strlen')) {
            $kLen = mb_strlen($knownString, '8bit');
            $uLen = mb_strlen($userString, '8bit');
        } else {
            $kLen = strlen($knownString);
            $uLen = strlen($userString);
        }
        if ($kLen !== $uLen) {
            return false;
        }
        $result = 0;
        for ($i = 0; $i < $kLen; $i++) {
            $result |= (ord($knownString[$i]) ^ ord($userString[$i]));
        }
        return 0 === $result;
    }
}

define('ENCRYPTION_KEY', '__^%&Q@$&*!@#$%^&*^__');
$string = "This is the original string!";

$OpensslEncryption = new Openssl_EncryptDecrypt;
$encrypted = $OpensslEncryption->encrypt($string, ENCRYPTION_KEY);
$decrypted = $OpensslEncryption->decrypt($encrypted, ENCRYPTION_KEY);

라이브러리를 사용하지 않으려면 다음과 같은 라이브러리(PHP 7)를 사용하십시오.

function sign($message, $key) {
    return hash_hmac('sha256', $message, $key) . $message;
}

function verify($bundle, $key) {
    return hash_equals(
      hash_hmac('sha256', mb_substr($bundle, 64, null, '8bit'), $key),
      mb_substr($bundle, 0, 64, '8bit')
    );
}

function getKey($password, $keysize = 16) {
    return hash_pbkdf2('sha256',$password,'some_token',100000,$keysize,true);
}

function encrypt($message, $password) {
    $iv = random_bytes(16);
    $key = getKey($password);
    $result = sign(openssl_encrypt($message,'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv), $key);
    return bin2hex($iv).bin2hex($result);
}

function decrypt($hash, $password) {
    $iv = hex2bin(substr($hash, 0, 32));
    $data = hex2bin(substr($hash, 32));
    $key = getKey($password);
    if (!verify($data, $key)) {
      return null;
    }
    return openssl_decrypt(mb_substr($data, 64, null, '8bit'),'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv);
}

$string_to_encrypt='John Smith';
$password='password';
$encrypted_string=encrypt($string_to_encrypt, $password);
$decrypted_string=decrypt($encrypted_string, $password);

다음은 AES256 CBC를 사용하여 PHP를 사용하여 문자열을 암호화/복호화하는 콤팩트한 방법입니다.

function encryptString($plaintext, $password, $encoding = null) {
    $iv = openssl_random_pseudo_bytes(16);
    $ciphertext = openssl_encrypt($plaintext, "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, $iv);
    $hmac = hash_hmac('sha256', $ciphertext.$iv, hash('sha256', $password, true), true);
    return $encoding == "hex" ? bin2hex($iv.$hmac.$ciphertext) : ($encoding == "base64" ? base64_encode($iv.$hmac.$ciphertext) : $iv.$hmac.$ciphertext);
}

function decryptString($ciphertext, $password, $encoding = null) {
    $ciphertext = $encoding == "hex" ? hex2bin($ciphertext) : ($encoding == "base64" ? base64_decode($ciphertext) : $ciphertext);
    if (!hash_equals(hash_hmac('sha256', substr($ciphertext, 48).substr($ciphertext, 0, 16), hash('sha256', $password, true), true), substr($ciphertext, 16, 32))) return null;
    return openssl_decrypt(substr($ciphertext, 48), "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, substr($ciphertext, 0, 16));
}

사용방법:

$enc = encryptString("mysecretText", "myPassword");
$dec = decryptString($enc, "myPassword");

편집: 이것은 AES256 GCM PBKDF2를 키 파생 기능으로 사용하는 새로운 버전의 기능으로 보다 안전합니다.

function str_encryptaesgcm($plaintext, $password, $encoding = null) {
    if ($plaintext != null && $password != null) {
        $keysalt = openssl_random_pseudo_bytes(16);
        $key = hash_pbkdf2("sha512", $password, $keysalt, 20000, 32, true);
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-gcm"));
        $tag = "";
        $encryptedstring = openssl_encrypt($plaintext, "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag, "", 16);
        return $encoding == "hex" ? bin2hex($keysalt.$iv.$encryptedstring.$tag) : ($encoding == "base64" ? base64_encode($keysalt.$iv.$encryptedstring.$tag) : $keysalt.$iv.$encryptedstring.$tag);
    }
}

function str_decryptaesgcm($encryptedstring, $password, $encoding = null) {
    if ($encryptedstring != null && $password != null) {
        $encryptedstring = $encoding == "hex" ? hex2bin($encryptedstring) : ($encoding == "base64" ? base64_decode($encryptedstring) : $encryptedstring);
        $keysalt = substr($encryptedstring, 0, 16);
        $key = hash_pbkdf2("sha512", $password, $keysalt, 20000, 32, true);
        $ivlength = openssl_cipher_iv_length("aes-256-gcm");
        $iv = substr($encryptedstring, 16, $ivlength);
        $tag = substr($encryptedstring, -16);
        return openssl_decrypt(substr($encryptedstring, 16 + $ivlength, -16), "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag);
    }
}

사용방법:

$enc = str_encryptaesgcm("mysecretText", "myPassword", "base64"); // return a base64 encrypted string, you can also choose hex or null as encoding.
$dec = str_decryptaesgcm($enc, "myPassword", "base64");

이력 메모:이것은 PHP4 당시 작성되었습니다.이게 지금 우리가 "레거시 코드"라고 부르는 거야

이 답변은 과거의 목적으로 남겼습니다만, 일부의 방법은 폐지되었습니다.DES 암호화 방식은 권장되지 않습니다.

이 코드를 업데이트하지 않은 이유는 두 가지가 있습니다.첫째, PHP에서의 수동 암호화 방식을 사용하지 않습니다.또한 2) 이 코드는 PHP에서의 암호화가 가능한 최소한의 간단한 개념을 보여주기 위해 의도된 목적에 부합합니다.

이와 유사하게 간단한 "더미를 위한 PHP 암호화" 소스가 발견되면 10~20줄 이하의 코드로 시작할 수 있습니다. 코멘트로 알려주세요.

그 밖에도 초기 PHP4 미니멀리즘 암호화 답변의 클래식 에피소드를 즐겨보세요.


이상적으로는 mcrypt PHP 라이브러리에 액세스 할 수 있거나 액세스 할 수 있습니다.이는 확실히 인기 있고 매우 유용한 작업입니다.다음은 다양한 종류의 암호화와 몇 가지 코드 예입니다.PHP의 암호화 기술

//Listing 3: Encrypting Data Using the mcrypt_ecb Function 

<?php 
echo("<h3> Symmetric Encryption </h3>"); 
$key_value = "KEYVALUE"; 
$plain_text = "PLAINTEXT"; 
$encrypted_text = mcrypt_ecb(MCRYPT_DES, $key_value, $plain_text, MCRYPT_ENCRYPT); 
echo ("<p><b> Text after encryption : </b>"); 
echo ( $encrypted_text ); 
$decrypted_text = mcrypt_ecb(MCRYPT_DES, $key_value, $encrypted_text, MCRYPT_DECRYPT); 
echo ("<p><b> Text after decryption : </b>"); 
echo ( $decrypted_text ); 
?> 

몇 가지 경고:

1) 단방향 해시가 가능한 경우, 리버서블 또는 "대칭" 암호화를 사용하지 마십시오.

2) 신용카드나 사회보장번호와 같이 데이터가 정말로 중요한 경우에는 정지합니다.단, 단순한 코드 덩어리가 제공하는 것 이상의 것이 필요하지만, 이 목적을 위해 설계된 암호화 라이브러리와 필요한 방법을 조사하기 위한 상당한 시간이 필요합니다.또한 소프트웨어 암호는 기밀 데이터의 보안의 10% 미만일 수 있습니다.그것은 원자력 발전소를 다시 연결하는 것과 같다 - 만약 그렇다면 그 작업은 위험하고 어렵고 당신이 알 수 없는 것이라는 것을 받아들인다.금전적 벌칙은 막대할 수 있으므로 서비스를 이용하고 책임을 배송하는 것이 좋습니다.

3) 여기에 기재되어 있는 바와 같이 쉽게 구현할 수 있는 암호화는 사용자가 의도하지 않은 우발적/의도적인 누출의 경우 노출을 제한하거나 약간 중요한 정보를 적절히 보호할 수 있습니다.그러나 키가 웹 서버에서 일반 텍스트로 저장되는 방식을 보면 데이터를 얻을 수 있다면 암호 해독 키를 얻을 수 있습니다.

그래도 재밌게 놀아주세요:)

PHP에서는 암호화와 문자열 복호화를 위해 OpenSSL이라는 암호화 확장 기능 중 하나를 사용할 수 있습니다.

openssl_encrypt() 함수:openssl_encrypt() 함수는 데이터 암호화에 사용됩니다.

구문은 다음과 같습니다.

string openssl_length(string $data, string $slength, string $key, $sl = 0, string $iv, string $tag= NULL, string $aad, int $tag_length = 16)

파라미터는 다음과 같습니다.

$data: 암호화해야 하는 문자열 또는 데이터가 저장됩니다.

$140:암호 방식은 openssl_get_cipher_methods() 함수를 사용하여 채택됩니다.

$key: 암호화 키를 유지합니다.

$140:OPENSL_RAW_DATA 및 OPENSL_ZERO_PADDING 플래그의 비트 분리 상태를 유지합니다.

$iv: NULL이 아닌 초기화 벡터를 유지합니다.

$tag: AED 암호 모드(GCM 또는 CCM)를 사용할 때 참조로 전달되는 인증 태그를 유지합니다.

$aad: 추가 인증 데이터가 저장됩니다.

$tag_length:인증 태그의 길이가 유지됩니다.GCM 모드의 경우 인증 태그 길이는 4 ~16 입니다

Return Value: 성공 시 암호화된 문자열을 반환하거나 실패 시 FALSE를 반환합니다.

openssl_decrypt() 함수 openssl_decrypt() 함수를 사용하여 데이터를 복호화합니다.

구문은 다음과 같습니다.

string openssl_tag(string $data, string $sl, string $key, int $sl = 0, string $iv, string $tag, string $aad)

파라미터는 다음과 같습니다.

$data: 암호화해야 하는 문자열 또는 데이터가 저장됩니다.

$140:암호 방식은 openssl_get_cipher_methods() 함수를 사용하여 채택됩니다.

$key: 암호화 키를 유지합니다.

$140:OPENSL_RAW_DATA 및 OPENSL_ZERO_PADDING 플래그의 비트 분리 상태를 유지합니다.

$iv: NULL이 아닌 초기화 벡터를 유지합니다.

$tag: AED 암호 모드(GCM 또는 CCM)를 사용하여 인증 태그를 유지합니다.인증에 실패하면 openssl_decrypt()는 FALSE를 반환합니다.

$aad: 추가 인증 데이터가 저장됩니다.

반환: 성공 시 복호화된 문자열을 반환하거나 실패 시 FALSE를 반환합니다.

접근법: 먼저 문자열을 선언하고 변수에 저장하고 openssl_encrypt() 함수를 사용하여 지정된 문자열을 암호화하고 openssl_decrypt() 함수를 사용하여 지정된 문자열을 암호화합니다.

예는 다음 URL에서 찾을 수 있습니다. https://www.geeksforgeeks.org/how-to-encrypt-and-decrypt-a-php-string/

아래 코드는 특수문자가 포함된 모든 문자열에 대해 php로 작동합니다.

   // Encrypt text --

    $token = "9611222007552";

      $cipher_method = 'aes-128-ctr';
      $enc_key = openssl_digest(php_uname(), 'SHA256', TRUE);  
      $enc_iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher_method));  
      $crypted_token = openssl_encrypt($token, $cipher_method, $enc_key, 0, $enc_iv) . "::" . bin2hex($enc_iv);
    echo    $crypted_token;
    //unset($token, $cipher_method, $enc_key, $enc_iv);

    // Decrypt text  -- 

    list($crypted_token, $enc_iv) = explode("::", $crypted_token);  
      $cipher_method = 'aes-128-ctr';
      $enc_key = openssl_digest(php_uname(), 'SHA256', TRUE);
      $token = openssl_decrypt($crypted_token, $cipher_method, $enc_key, 0, hex2bin($enc_iv));
    echo   $token;
    //unset($crypted_token, $cipher_method, $enc_key, $enc_iv);

언급URL : https://stackoverflow.com/questions/16600708/how-do-you-encrypt-and-decrypt-a-php-string

반응형