tutorial - php salt




PHP 암호를위한 안전한 해시 및 소금 (10)

현재 MD5가 부분적으로 안전하지 않다고합니다. 이것을 고려하여 암호 보호에 사용할 메커니즘을 알고 싶습니다.

이 질문 은 "이중 해싱"은 암호를 한 번 해시하는 것보다 덜 안전합니까? 여러 번 해시하는 것이 좋은 생각 일 수 있다고 제안하는 반면, 개별 파일에 대한 암호 보호를 구현 하는 방법은 무엇입니까? 소금 사용을 제안합니다.

PHP를 사용하고 있습니다. 나는 안전하고 빠른 암호 암호화 시스템을 원한다. 백만 번 암호를 해싱하는 것이 더 안전 할 수도 있지만 느려질 수도 있습니다. 속도와 안전 사이의 균형을 어떻게 이루는가? 또한, 나는 그 결과가 일정한 수의 문자를 가지길 원합니다.

  1. 해시 메커니즘은 PHP에서 사용할 수 있어야합니다.
  2. 안전해야합니다.
  3. 그것은 소금을 사용할 수 있습니다 (이 경우 모든 소금이 똑같이 좋은가? 좋은 소금을 생성 할 수있는 방법이 있습니까?)

또한 데이터베이스에 두 개의 필드를 저장해야합니까 (하나는 MD5를 사용하고 다른 하나는 SHA를 사용합니다). 그것이 더 안전하거나 불공평하게 만들겠습니까?

내가 충분히 명확하지 않은 경우, 안전하고 빠른 암호 보호 메커니즘을 사용하기 위해 사용할 해싱 함수와 올바른 소금을 선택하는 방법을 알고 싶습니다.

내 질문에 대해 다루지 않는 관련 질문 :

PHP에서 SHA와 MD5의 차이점은 무엇입니까?
간단한 암호 암호화
asp.net에 대한 키, 암호 저장의 안전한 방법
Tomcat 5.5에서 소금에 절인 암호를 어떻게 구현합니까?


면책 조항 :이 답변은 2008 년에 작성되었습니다.

그 이후로 PHP는 php.net/manual/en/function.password-hash.phppassword_verify 했으며, 소개 이후 권장되는 해싱 및 검사 방법입니다.

대답의 이론은 여전히 ​​좋은 읽을 거리입니다.

TL, DR

하지 말아야 할 것

  • 사용자가 암호를 입력 할 수있는 문자를 제한하지 마십시오. 단지 바보가 이것을한다.
  • 암호의 길이를 제한하지 마십시오. 사용자가 supercalifragilisticexpialidious 인 문장을 원한다면 사용하지 못하게하십시오.
  • 사용자의 암호를 일반 텍스트로 저장하지 마십시오.
  • 비밀번호를 잊어 버린 경우를 제외하고 는 비밀번호를 이메일로 보내지 마시고 임시 비밀번호를 보내주십시오.
  • 어떠한 방식 으로든 절대로 암호를 기록하지 마십시오.
  • SHA1 또는 MD5 또는 심지어 SHA256으로 암호를 해시하지 마십시오! 현대 크래커 는 초당 60 억 개에서 180 억 개를 초과 할 수 있습니다.
  • bcrypt와 hash ()의 raw 출력을 섞지 마십시오. hex 출력을 사용하거나 base64_encode를 사용하십시오. (이것은 불량 \0 하고있어 보안을 심각하게 약화시킬 수있는 모든 입력에 적용됩니다.)

도스

  • 가능한 경우 scrypt를 사용하십시오. 당신이 할 수 없다면 bcrypt.
  • bcrypt 또는 scrypt를 사용할 수 없으면 SHA2 해시와 함께 PBKDF2를 사용하십시오.
  • 데이터베이스가 손상되면 모든 사람의 암호를 재설정하십시오.
  • 합리적인 8-10 문자의 최소 길이를 구현하고 최소 1 개의 대문자, 1 개의 소문자, 숫자 및 기호가 필요합니다. 이렇게하면 암호의 엔트로피가 향상되어 균열이 더 힘들어집니다. (몇 가지 토론에 대해서는 "무엇이 좋은 암호입니까?"섹션을 참조하십시오.)

어쨌든 해시 암호가 필요한 이유는 무엇입니까?

암호 해시의 목적은 간단합니다. 데이터베이스를 손상시켜 사용자 계정에 대한 악의적 인 액세스를 방지합니다. 따라서 암호 해싱의 목표는 일반 텍스트 암호를 계산하는 데 너무 많은 시간이나 비용을 들여 해커 나 크래커를 막는 것입니다. 그리고 시간 / 비용이 당신의 무기고에서 가장 좋은 방어벽입니다.

사용자 계정에 양호하고 강력한 해시가 필요한 또 다른 이유는 시스템의 모든 암호를 변경할 충분한 시간을 제공하기 위해서입니다. 데이터베이스가 손상된 경우 데이터베이스의 모든 암호를 변경하지 않으면 최소한 시스템을 잠글 수있는 충분한 시간이 필요합니다.

화이트 햇 시큐리티의 CTO 인 Jeremiah Grossman은 최근 패스워드를 복구 한 후에 그의 블로그 에서 패스워드 보호를 무차별 적으로 파괴해야 한다고 말했다 :

흥미롭게도,이 악몽에 빠져들 때, 나는 패스워드 크래킹, 저장 및 복잡성에 대해 몰랐다. 암호 저장이 암호 복잡성보다 훨씬 중요한 이유를 알아 보았습니다. 암호 저장 방법을 모르면 실제로 의존 할 수있는 것은 복잡합니다. 이것은 패스워드 및 암호 전문가들에게는 공통적 인 지식 일 수 있지만, 평균적인 InfoSec 또는 Web Security 전문가에게는 매우 의심 스럽습니다.

(강조 광산.)

어쨌든 좋은 암호를 만드는 이유는 무엇입니까?

Entropy . (Randall의 견해에 완전히 동의하지는 않습니다.)

간단히 말해서, 엔트로피는 암호 내에 얼마나 많은 변화가 있는지입니다. 암호가 소문자 로마자 일 경우에만 26 문자입니다. 그다지 변하지 않습니다. 36 자리 문자로 된 영숫자 암호가 더 좋습니다. 그러나 대문자와 소문자를 허용하려면 약 96 자입니다. 그것은 단순한 편지보다 훨씬 낫습니다. 한 가지 문제는 암호를 기억하기 쉽도록 패턴을 삽입함으로써 엔트로피를 줄이는 것입니다. 죄송합니다.

암호 엔트로피는 쉽게 approximated 할 수 있습니다. 전체 ASCII 문자 (약 96 개의 문자)를 사용하면 암호 당 8 자의 엔트로피가 6.6의 엔트로피를 산출하여 향후 보안을 위해 여전히 너무 낮습니다 (52.679 비트의 엔트로피). 그러나 좋은 소식은 더 긴 패스워드와 유니 코드 문자로 된 패스워드로 패스워드의 엔트로피를 증가시키고 크랙을 어렵게 만드는 것입니다.

Crypto StackExchange 사이트에서 암호 엔트로피에 대한 더 자세한 논의가 있습니다. 좋은 Google 검색은 또한 많은 결과를 보여줍니다.

X에서 많은 문자, 숫자, 기호 등을 사용하여 X 길이의 암호 정책을 적용 하면 실제로 암호 체계를보다 예측 가능하게 만들어 엔트로피를 줄일 수 있다고 지적한 @popnoodles와 의견을 나누었습니다. 나는 동의한다. 가능한 임의의 임의적 인 임의성은 항상 가장 안전하면서도 가장 기억에 남는 솔루션입니다.

지금까지 말했듯이 세계 최고의 암호를 만드는 것은 Catch-22입니다. 너무 기억하기 쉽고, 예측할 수없고, 너무 짧고, 너무 많은 유니 코드 문자 (Windows / 모바일 장치에 입력하기 힘들다), 너무 길거나 등등. 우리의 목적을 위해 암호가 실제로 충분하지 않으므로 암호를 보호해야합니다. 포트 녹스에 있었다.

모범 사례

Bcrypt와 scrypt 는 현재의 베스트 프랙티스입니다. scrypt 는 시간상 bcrypt보다 좋지만 Linux / Unix 또는 웹 서버는 표준으로 채택하지 못했으며 아직 게시 된 알고리즘에 대한 심층적 인 검토는하지 않았습니다. 그러나 여전히 알고리즘의 미래는 유망 해 보인다. Ruby로 작업하는 경우 도움이 될만한 scrypt gem 이 있습니다. 이제 Node.js에는 자체 scrypt 패키지가 있습니다. Scrypt 확장자 또는 Libsodium 확장자를 통해 PHP에서 Scrypt를 사용할 수 있습니다 (둘 다 PECL에서 사용 가능함).

필자는 bcrypt를 사용하는 방법을 이해하거나 더 openwall.com/phpass wrapper 찾거나 더 많은 레거시 구현을 위해 openwall.com/phpass 와 같은 것을 사용하려는 경우 crypt 함수에 대한 설명서를 읽는 것이 좋습니다. 적어도 15 회에서 18 회까지는 bcrypt를 12 회 이상 권장합니다.

나는 bcrypt가 복어의 주요 일정만을 가변 비용 메커니즘으로 사용한다는 것을 배웠을 때 bcrypt 사용에 대한 생각을 바꾸었다. 후자는 복어의 벌써 비싼 주요 일정을 늘림으로써 암호를 무차별 공격으로 증가시킬 수 있습니다.

평균 관행

나는이 상황을 더 이상 상상할 수 없다. openwall.com/phpass 는 PHP 3.0.18에서 5.3까지를 지원하므로, 거의 모든 설치 환경에서 사용할 수 있으며, 여러분의 환경이 bcrypt를 지원 하는지 모를 경우 사용해야합니다.

그러나 bcrypt 나 PHPASS를 전혀 사용할 수 없다고 가정하십시오. 그 때 무엇?

환경 / 애플리케이션 / 사용자 인식이 용인 할 수있는 최대 라운드 수를 사용하여 PDKBF2 구현을 시도하십시오. 가장 낮은 번호는 2500 라운드입니다. 또한 hash_hmac() 를 재생하기가 더 어렵게 만들 수있는 경우 hash_hmac() 를 사용해야합니다.

미래 관행

PHP 5.5는 bcrypt로 작업 할 때 발생하는 모든 문제를 추상화하는 완벽한 암호 보호 라이브러리 입니다. 대부분의 사람들이 가장 일반적인 환경, 특히 공유 호스트에서 PHP 5.2 및 5.3을 사용하지만 @ircmaxell은 PHP 5.3.7과 역 호환되는 향후 API의 호환성 레이어 를 구축했습니다.

암호화 개요 및 면책 조항

실제로 해시 된 암호를 해독 하는 데 필요한 계산 능력은 존재하지 않습니다. 컴퓨터가 암호를 "해독"하는 유일한 방법은 암호를 다시 작성하고이를 보호하는 데 사용되는 해시 알고리즘을 시뮬레이트하는 것입니다. 해쉬의 속도는 짐승 같은 능력에 선형 적으로 관련이 있습니다. 더 나쁜 것은 대부분의 해시 알고리즘을 더 쉽게 병렬 처리하여 더 빠르게 수행 할 수 있다는 것입니다. 이것이 왜 bcrypt와 scrypt와 같은 값 비싼 계획이 중요한지입니다.

모든 위협이나 공격 경로를 미리 예측할 수는 없으므로 사용자를 최우선으로 보호해야합니다. 그렇게하지 않으면 너무 늦을 때까지 공격 당했다는 사실을 놓칠 수도 있습니다 ... 그리고 당신은 책임이 있습니다. 이러한 상황을 피하려면 편집증 환자로 시작하십시오. 자신의 소프트웨어를 공격하여 (내부적으로) 사용자 자격 증명을 도용하거나 다른 사용자의 계정을 수정하거나 데이터에 액세스하십시오. 시스템의 보안을 테스트하지 않으면 자신을 제외한 모든 사람을 탓할 수 없습니다.

마지막으로 : 저는 암호 작성자가 아닙니다. 제가 말한 것은 제 의견이지만, 저는 그것이 좋은 올 상식과 ... 많은 독서에 근거한다고 생각합니다. 가능한 한 편집성에 빠져들고, 가능한 한 방해하지 못하게하고, 여전히 걱정이된다면, 화이트 햇 해커 또는 암호 작성자에게 연락하여 코드 / 시스템에 대한 의견을 확인하십시오.


Google은 SHA256을 PHP에서 사용할 수 있다고 말합니다.

확실히 소금을 사용해야합니다. 난 임의의 바이트를 사용하는 것이 좋습니다 (그리고 문자와 숫자에 국한되지 않음). 일반적으로 선택할수록 안전하고 느립니다. 64 바이트는 괜찮을 것입니다.


PHP 5.5에는 crypt() 주위에 래퍼를 제공하는 암호 해시 API 가 포함되어 있습니다. 이 API는 암호 해시의 해시, 확인 및 재 해싱 작업을 크게 단순화합니다. 저자는 PHP 5.3.7 이상을 사용하는 사람들을 위해 (지금 사용하고 싶은 password.php 파일 형태로) 호환성 팩을 발표했다.

현재는 BCRYPT 만 지원하지만 다른 암호 해싱 기술을 포함하도록 쉽게 확장 할 수 있으며 기술 및 비용이 해시의 일부로 저장되므로 원하는 해싱 기법 / 비용을 변경해도 현재 해시가 무효화되지는 않습니다. 자동적으로 유효성을 검사 할 때 올바른 기술 / 비용을 사용합니다. 또한 자신이 명시 적으로 정의하지 않으면 "안전한"소금 생성을 처리합니다.

API는 네 가지 기능을 제공합니다.

  • password_get_info() - 주어진 해시에 대한 정보를 반환합니다.
  • password_hash() - 암호 해시를 만듭니다.
  • password_needs_rehash() - 주어진 해시가 주어진 옵션과 일치하는지 확인합니다. 필요한 경우 다시 해시 할 수 있도록 해시가 현재 기술 / 비용 체계를 준수하는지 확인하는 데 유용합니다.
  • password_verify() - 암호가 해시와 일치하는지 확인합니다.

현재이 함수들은 현재 동의어 인 PASSWORD_BCRYPT와 PASSWORD_DEFAULT 암호 상수를 받아들입니다. 그 차이점은 PASSWORD_DEFAULT가 더 새롭고 강력한 해싱 알고리즘이 지원 될 때 새로운 PHP 릴리스에서 변경 될 수 있다는 것입니다. 로그인시 PASSWORD_DEFAULT 및 password_needs_rehash ()를 사용하여 (필요한 경우 다시 해싱) 해시 작업을 거의 또는 전혀하지 않고 무차별 공격에 적절하게 복원 할 수 있어야합니다.

편집 : 나는 방금 로버트 케이의 대답에 간략하게 언급 된 것을 깨달았다. 나는 그것이 작동하는 방법과 보안을 모르는 사람들에게 제공되는 사용의 용이성에 대한 약간의 정보를 제공한다고 생각하기 때문에이 대답을 남겨 둘 것입니다.


거의 모든 PHP 프로젝트에서 매우 쉽게 구현할 수있는 간단한 단일 파일 PHP 클래스 인 openwall.com/phpass 를 사용하고 있습니다. The H.를 보라.

기본적으로 Phpass에서 구현 된 가장 강력한 가용 암호화를 사용했습니다.이 암호화는 bcrypt 이며 Wordpress와 같은 프레임 워크에 대한 하위 호환성을 제공하기 위해 MD5까지 다른 암호화로 bcrypt 합니다.

반환 된 해시는 그대로 데이터베이스에 저장 될 수 있습니다. 해시 생성을위한 샘플 사용은 다음과 같습니다.

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

암호를 확인하려면 다음을 사용할 수 있습니다.

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);

이 문제에 관해서는 여기에서 완벽한 주제를 찾았습니다 : https://crackstation.net/hashing-security.htm , 나는 당신이 그것으로부터 이익을 얻길 원했으며, 여기에 시간 기반 공격에 대한 예방을 제공하는 소스 코드도 있습니다.

<?php
/*
 * Password hashing with PBKDF2.
 * Author: havoc AT defuse.ca
 * www: https://defuse.ca/php-pbkdf2.htm
 */

// These constants may be changed without breaking existing hashes.
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 1000);
define("PBKDF2_SALT_BYTES", 24);
define("PBKDF2_HASH_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

/*
 * 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
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $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));
}
?>

질문에 대한 대답은 있었지만, 해싱에 사용 된 소금은 첫 번째 대답에서 제안 된 것처럼 전자 메일 주소와 무관하게 반복되어야한다고 반복하고 싶습니다.

자세한 설명은 http://www.pivotalsecurity.com/blog/password-hashing-salt-should-it-be-random/ 수 있습니다 http://www.pivotalsecurity.com/blog/password-hashing-salt-should-it-be-random/

최근에는 암호 해시가 임의의 비트로 소금물에 잠겼는지 여부가 추측 할 수 있거나 알려진 소금으로 소금을 넣은 것보다 안전한지 여부에 대한 토론이있었습니다. 암호를 저장하는 시스템과 무작위 소금을 저장하는 시스템이 침입자가 해시뿐만 아니라 소금에 액세스 할 수 있으므로 소금이 무작위인지 아닌지 여부는 중요하지 않습니다. 공격자는 해시를 해독하기 위해 미리 계산 된 무지개 테이블을 생성 할 수 있습니다. 여기서 흥미로운 부분이 있습니다. 사전 계산 된 테이블을 생성하는 것은 그리 간단하지 않습니다. WPA 보안 모델의 예를 들어 보겠습니다. WPA 암호는 실제로 무선 액세스 포인트로 전송되지 않습니다. 대신 SSID (네트워크 이름 - Linksys, Dlink 등)로 해싱됩니다. 이것이 어떻게 작동하는지에 대한 아주 좋은 설명이 여기에 있습니다. 해시에서 암호를 검색하려면 salt (네트워크 이름)와 암호를 알아야합니다. Church of Wifi에는 이미 1000 개의 SSID와 약 1 백만 개의 암호가있는 해시 테이블이 미리 계산되어 있습니다. 모든 테이블의 크기는 약 40GB입니다. 그들의 사이트에서 읽을 수 있듯이 누군가는 15 일 FGPA 어레이를 사용하여 3 일 동안이 테이블을 생성했습니다. 피해자가 "a387csf3"으로 SSID를 사용하고 "123456"으로 암호를 사용한다고 가정하면이 테이블에 의해 금이 갈 것입니까? 아니! .. 그럴 순 없어. 암호가 약한 경우에도 테이블에는 SSID a387csf3에 대한 해시가 없습니다. 이것은 무작위로 소금을 가지고있는 아름다움입니다. 사전 계산 된 테이블에서 번창하는 크래커를 막을 것입니다. 해커를 막을 수 있습니까? 아마도 그렇지 않습니다. 그러나 무작위 염을 사용하면 추가적인 방어막이 생깁니다. 이 주제를 다루는 동안, 무작위 염을 별도의 시스템에 저장하는 추가적인 이점에 대해 논의합시다. 시나리오 # 1 : 암호 해시가 시스템 X에 저장되고 해시에 사용되는 소금 값이 시스템 Y에 저장됩니다.이 소금 값은 추측 가능하거나 알려져 있습니다 (예 : 사용자 이름) 시나리오 2 : 암호 해시는 시스템 X에 저장되고 소금 값은 해싱은 시스템 Y에 저장됩니다. 이러한 소금 값은 임의적입니다. 추측 할 수 있듯이 시스템 X가 손상된 경우 별도의 시스템에서 무작위 소금을 사용하는 것이 큰 이점이 있습니다 (시나리오 # 2). 공격자는 해시를 해독 할 수 있도록 추가 값을 추측해야합니다. 32 비트 솔트가 사용된다면, 추측 된 각 패스워드마다 2 ^ 32 = 4,294,967,296 (약 42 억) 반복이 필요할 수 있습니다.


SHA1가까운 장래에 SHA1 과 소금으로 충분할 것입니다 (당연히, Fort Knox 또는 쇼핑 목록의 로그인 시스템에 무엇을 코딩하고 있느냐 에 따라 다릅니다 ). SHA1이 충분하지 않은 경우 SHA256 사용하십시오 .

소금에 대한 아이디어는 해싱 결과를 균형을 잃어 버리는 것입니다. 예를 들어 빈 문자열의 MD5 해시가 알려져 d41d8cd98f00b204e9800998ecf8427e있습니다. 따라서 메모리가 충분한 사람이 해시를보고 빈 문자열의 해시라는 것을 알고있는 경우 그러나 문자열에 소금이 들어 있다면 (예 : 문자열 " MY_PERSONAL_SALT"), '빈 문자열'(즉, " ")에 대한 해시 MY_PERSONAL_SALTaeac2612626724592271634fb14d3ea6되므로 역 추적에 명확하지 않습니다. 내가 말하려고하는 것은 소금 을 사용 하는 것이 낫다는 것보다 더 좋습니다 . 따라서 알고 중요성을 너무 많이 아닙니다 하는 사용하는 소금.

실제로 이것을 수행하는 웹 사이트가 있습니다. 즉 , (md5) 해시를 제공 할 수 있으며 특정 해시를 생성하는 알려진 일반 텍스트를 출력합니다. 일반 md5 해시를 저장하는 데이터베이스에 액세스하려면 해당 서비스에 대한 관리자의 해시를 입력하고 로그인하는 것이 사소한 것입니다. 그러나 비밀번호가 소금에 절인 경우 이러한 서비스는 효과적인.

또한, 이중 해싱은 일반적으로 나쁜 방법으로 간주됩니다. 결과 공간이 줄어들 기 때문입니다. 모든 인기있는 해시는 고정 길이입니다. 따라서이 고정 길이의 유한 값만 가질 수 있으며 결과는 다양하지 않게됩니다. 이것은 다른 형태의 염분으로 간주 수 있지만, 나는 그것을 권장하지 않습니다.


기억해야 할 것

PHP에 대한 암호 암호화에 관해서는 많은 이야기가있었습니다. 대부분은 좋은 조언이지만, 암호 암호화를 위해 PHP를 사용하기 전에 다음을 구현하거나 구현할 준비가되어 있는지 확인하십시오.

섬기는 사람

포트

PHP와 DB를 실행하는 서버를 안전하게 보호하지 않으면 암호화가 아무리 훌륭해도 모든 노력은 쓸모가 없습니다. 대부분의 서버는 상대적으로 동일한 방식으로 작동하며 ftp 또는 셸을 통해 원격으로 액세스 할 수 있도록 포트가 할당되어 있습니다. 원격 연결이 활성화 된 기본 포트를 변경했는지 확인하십시오. 이렇게하지 않으면 침입자가 실제로 시스템에 액세스하는 단계를 한 단계 단축 할 수 있습니다.

사용자 이름

세상에서 좋은 모든 것을 사용자 이름 admin, root 또는 유사한 것으로 사용하지 마십시오. 또한 유닉스 기반 시스템에 있다면 루트 계정 로그인을 액세스 가능하게하지 마십시오. 항상 sudo 만 사용해야합니다.

암호

해킹 당하지 않도록 사용자에게 올바른 비밀번호를 알려주는 것도 마찬가지입니다. 백도어가 활짝 열려있을 때 현관 문을 잠그기위한 모든 노력을 기울이는 데 필요한 점은 무엇입니까?

데이터 베이스

섬기는 사람

DB와 APPLICATION을 별도의 서버에 설치하는 것이 이상적입니다. 이는 비용 때문에 항상 가능하지는 않지만 침입자가 시스템에 완전히 액세스하려면 두 단계를 거쳐야하므로 몇 가지 안전을 허용합니다.

사용자

DB에 액세스하려면 응용 프로그램에 항상 자체 계정이 있어야하며 필요한 권한 만 부여하십시오.

그런 다음 응용 프로그램이 아닌 서버의 어느 곳에도 저장되어 있지 않은 별도의 사용자 계정을 보유하십시오.

항상이 루트 또는 이와 유사한 것을 만들지 마세요.

암호

모든 좋은 암호와 동일한 지침을 따르십시오. 또한 동일한 시스템의 SERVER 또는 DB 계정에서 동일한 암호를 다시 사용하지 마십시오.

PHP

암호

절대 DB에 암호를 저장하지 말고 해시와 고유 한 소금을 저장하십시오. 이유는 나중에 설명하겠습니다.

해싱

한 번 해싱 !!!!!!! 절대 암호를 해싱 할 수 없도록 해시하지 마십시오. 해시는 한 가지 방법이어야합니다. 즉, 해시를 되돌려서 암호와 비교하지 말고 대신 입력 된 암호를 해시합니다 같은 방법으로 두 개의 해시를 비교합니다. 즉, 공격자가 DB에 액세스하더라도 실제로 암호가 무엇인지 알지 못하고 결과 해시 만 알 수 있습니다. 최악의 시나리오에서 사용자에게 더 많은 보안을 제공합니다.

거기에 좋은 해싱 함수 ( password_hash , hash , 등등 ...) 밖에 많이 있지만 해시에 대한 효과적인 알고리즘을 선택해야합니다. (bcrypt와 비슷한 것들은 알맞은 알고리즘이다.)

해싱 속도가 중요 할 때, Brute Force 공격에 대한 저항력은 낮아집니다.

해싱에서 가장 흔한 실수 중 하나는 해시가 사용자에게 고유하지 않다는 점입니다. 소금이 유일하게 생성되지 않기 때문입니다.

판매

암호는 해시되기 전에 항상 소금을해야합니다. Salting은 암호에 임의의 문자열을 추가하여 DB에 동일한 암호가 나타나지 않도록합니다. 그러나 소금이 각 사용자에게 고유하지 않은 경우 (예 : 하드 코드 된 소금을 사용하는 경우) 소금을 쓸모 없게 만들었습니다. 한 번 공격자가 암호 소금을 알아 내면 그는 모두를 위해 소금을 가지고 있기 때문에.

소금을 만들 때 소금에 고유 한 암호인지 확인한 다음 완성 된 해시와 소금을 DB에 저장하십시오. 이렇게하면 공격자가 액세스하기 전에 소금과 해시를 개별적으로 해킹해야합니다. 이는 공격자가 더 많은 작업과 시간을 가질 수 있음을 의미합니다.

사용자가 암호를 생성합니다.

사용자가 프론트 엔드를 통해 암호를 작성하면 서버로 보내야 함을 의미합니다. 이는 암호화되지 않은 암호가 서버로 전송되고 공격자가 PHP의 모든 보안이 무의미하다는 것을 경청하고 액세스 할 수 있다는 것을 의미하므로 보안 문제가 발생합니다. 항상 데이터를 안전하게 전송합니다. SSL을 통해 이루어 지지만 SSL이 완벽하지는 않습니다 (OpenSSL의 Heartbleed 결함이 이에 대한 예입니다).

또한 사용자가 안전한 암호를 만들도록하십시오. 간단하고 항상 수행해야합니다. 사용자는 결국 그것을 감사하게됩니다.

마지막으로 아무런 보안 조치를 취하지 않아도 100 % 보안을 유지할 수 있으므로 보호 할 기술이 진보할수록 더욱 발전합니다. 그러나이 단계를 따르면 사이트가 더 안전 해지고 공격자가 계속해서 나아갈 수 없게됩니다.

다음은 패스워드 해시와 소금을 쉽게 생성하는 PHP 클래스입니다.

http://git.io/mSJqpw


우리가 필요로하는 깔끔한 소금 소금은 독창적이어야하므로 그것을 생성시켜야합니다.

   /**
     * Generating string
     * @param $size
     * @return string
     */
    function Uniwur_string($size){
        $text = md5(uniqid(rand(), TRUE));
        RETURN substr($text, 0, $size);
    }

또한 해시가 필요합니다. sha512를 사용하고 있습니다. PHP가 최고입니다.

   /**
     * Hashing string
     * @param $string
     * @return string
     */
    function hash($string){
        return hash('sha512', $string);
    }

그래서 지금 우리는이 함수를 사용하여 안전한 암호를 생성 할 수 있습니다.

// generating unique password
$password = Uniwur_string(20); // or you can add manual password
// generating 32 character salt
$salt = Uniwur_string(32);
// now we can manipulate this informations

// hashin salt for safe
$hash_salt = hash($salt);
// hashing password
$hash_psw = hash($password.$hash_salt);

이제 $ hash_psw 변수 값과 $ salt 변수를 데이터베이스에 저장해야합니다.

권한을 부여하기 위해 동일한 단계를 사용합니다 ...

그것은 고객의 암호를 안전하게하는 가장 좋은 방법입니다 ...

추신 : 마지막 2 단계 당신은 자신의 알고리즘을 사용할 수 있습니다 ...하지만 당신은 당신이 사용자를 승인해야 할 때 미래에 해시 된 암호를 생성 할 수 있는지 확인하십시오 ...


결국, double-hashing은 수학적으로 이점을 제공하지 못합니다. 그러나 실제로는 레인보우 테이블 기반 공격을 막는 데 유용합니다. 즉, 소금으로 해싱하는 것보다 더 이상 이점이 없습니다. 이는 응용 프로그램이나 서버에서 프로세서 시간이 훨씬 단축됩니다.





protection