PHP를 사용하여 암호를 암호화하고 해독하는 가장 좋은 방법은? [복제하다

StackOverflow https://stackoverflow.com/questions/1289061

문제

가능한 복제 :
PHP 2 방향 암호화 : 검색 할 수있는 암호를 저장해야합니다.

내 웹 사이트, 일명 RapidShare 사용자 이름 및 비밀번호 등에 사용자에 대한 외국 계정 정보를 저장할 계획입니다 ... 정보를 안전하게 유지하고 싶지만 정보를 해시하면 나중에 사용하기 위해 검색 할 수 없다는 것을 알고 있습니다. .

Base64는 해독 할 수 있으므로 그 단지 평범한 오프를 사용하는 점이 없습니다. 내 아이디어는 사용자를 스크램블하고 해독 한 후에도 Base64를 전후에 통과시키는 것입니다. 해독하려고하면 재미있는 텍스트를 얻을 수 있습니다. 문자열의 고유 한 스크램블을 만들고 나중에 값이 다시 보일 때 스캔 할 수있는 값을 수용하는 PHP 함수가 있습니까?

제안이 있습니까?

도움이 되었습니까?

해결책

비밀번호를 암호화해서는 안되며 대신 Bcrypt와 같은 알고리즘을 사용하여 해시해야합니다. 이 답변은 PHP에서 암호 해싱을 올바르게 구현하는 방법을 설명합니다.. 그래도 다음은 다음과 같은 방법입니다.

$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces

암호화 :

$iv = mcrypt_create_iv(
    mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
    MCRYPT_DEV_URANDOM
);

$encrypted = base64_encode(
    $iv .
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        $string,
        MCRYPT_MODE_CBC,
        $iv
    )
);

해독하려면 :

$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

$decrypted = rtrim(
    mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
        MCRYPT_MODE_CBC,
        $iv
    ),
    "\0"
);

경고: 위의 예제는 정보를 암호화하지만 암호화를 방지하기 위해 암호 텍스트를 인증하지는 않습니다. 당신은해야합니다 ~ 아니다 보안을위한 무단 암호화에 의존하십시오, 특히 제공된 코드는 오라클 공격을 패딩하는 데 취약하기 때문에.

또한보십시오:

또한 암호화 키에 "비밀번호"만 사용하지 마십시오. 암호화 키는 임의의 문자열입니다.


3v4l.org에서 데모:

echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="

echo "\n";

echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "

다른 팁

보안 경고:이 수업은 안전하지 않습니다. 사용 중입니다 Rijndael256-ECB, 의미 적으로 안전하지 않습니다. "작동"이 "안전하다"는 의미는 아닙니다. 또한 적절한 패딩을 사용하지 않아서 테일링 공간을 벗겨냅니다.

최근 에이 수업을 발견했습니다. 꿈처럼 작동합니다!

class Encryption {
    var $skey = "yourSecretKey"; // you can change it

    public  function safe_b64encode($string) {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_',''),$data);
        return $data;
    }

    public function safe_b64decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public  function encode($value){ 
        if(!$value){return false;}
        $text = $value;
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
        return trim($this->safe_b64encode($crypttext)); 
    }

    public function decode($value){
        if(!$value){return false;}
        $crypttext = $this->safe_b64decode($value); 
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
        return trim($decrypttext);
    }
}

그리고 그것을 부르기 위해 :

$str = "My secret String";

$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);    

echo "$encoded<p>$decoded";

보안 경고: 이 코드는 안전하지 않습니다.

작업 예

define('SALT', 'whateveryouwant'); 

function encrypt($text) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 

$encryptedmessage = encrypt("your message"); 
echo decrypt($encryptedmessage); 

암호화를 다룰 때 매우 알아야 할 사항 :

영리하고 자신의 물건을 발명하려고 시도하면 보통 불안한 무언가를 남길 것입니다.

당신은 아마도 그 중 하나를 사용하는 것이 가장 좋을 것입니다 암호화 확장 PHP와 함께 제공됩니다.

이것은 당신에게 단지 한계 보호를 줄 것입니다. 공격자가 응용 프로그램에서 임의의 코드를 실행할 수있는 경우 응용 프로그램이 할 수있는 방식과 정확히 동일한 방식으로 비밀번호를 얻을 수 있습니다. 파일에 비밀 키를 저장하고 DB로가는 도중에 암호화하고 탈출 할 때 암호를 암호화하는 데 사용하는 경우 일부 SQL 주입 공격 및 잘못 배치 된 DB 백업으로부터 보호를받을 수 있습니다. 그러나 SQL 주입 문제를 완전히 피하려면 Bindparam을 사용해야합니다.

암호화로 결정한 경우,이를 위해 높은 수준의 암호화 라이브러리를 사용해야합니다. ~ 할 것이다 잘못 이해하십시오. 키 세트, 메시지 패딩 및 무결성 검사를 정확하게 가져와야합니다. 또는 모든 암호화 노력은 거의 사용되지 않습니다. GPGME 한 예에 대한 좋은 선택입니다. McRypt는 너무 낮은 수준이어서 아마도 잘못 될 것입니다.

안전한 경고:이 코드입니다 불안정한. 선택된 심목 텍스트 공격에 취약 할뿐만 아니라 unserialize() PHP 객체 주입에 취약합니다.

문자열 / 배열을 처리하기 위해이 두 기능을 사용합니다.

function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), '+/=', '-_,');
 return $s;
}

function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, '-_,', '+/=')), MCRYPT_MODE_CBC, md5(md5($key))), "\0"));
 return $s;
}

문자열/배열이 암호화되기 전에 붕대되기 때문에 문자열 또는 배열을 통해 저장/보낼 수있는 것처럼 유연합니다.

myCrypt ()를 확인하십시오. http://us.php.net/manual/book.mcrypt.php

Postgres를 사용하는 경우 데이터베이스 레벨 암호화 용 PGCRYPTO가 있습니다. (검색하고 정렬하기가 더 쉬워짐)

코드에 액세스 할 수 있더라도 데이터베이스에서 데이터를 암호화/해독하는 가장 좋은 아이디어는 2 개의 다른 패스를 사용하는 것이 좋습니다 (개인 비밀번호).user-pass) 각 사용자 및 모든 사용자의 개인 코드에 대해 (system-pass).

대본

  1. user-pass 데이터베이스에 MD5에 저장되며 각 사용자가 시스템에 로그인하도록 유효성을 검사하는 데 사용됩니다. 이 사용자 통과입니다 다른 각 사용자에 대해.
  2. 데이터베이스의 각 사용자 항목에는 MD5 A가 있습니다. system-pass 데이터의 암호화/암호 해독. 이 시스템 패스는 같은 각 사용자에 대해.
  3. 사용자가 시스템에서 제거 될 때마다 기존 시스템 통과에 따라 암호화 된 모든 데이터는 보안 문제를 피하기 위해 새로운 시스템 패스로 다시 암호화해야합니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top