programing

PHP의 해시에 bcrypt를 사용하는 방법은 무엇입니까?

yoursource 2022. 11. 1. 22:56
반응형

PHP의 해시에 bcrypt를 사용하는 방법은 무엇입니까?

"PHP, bcrypt 규칙에 패스워드를 저장하기 위해 bcrypt를 사용하세요"라는 조언을 가끔 듣습니다.

★★★★★★★★★★★★★★★★★★★★★bcryptPHP는 이러한 기능을 제공하지 않습니다.Wikipedia에서는 파일 암호화 유틸리티에 대해 횡설수설하고 있습니다.웹 검색에서는 Blowfish의 가지 다른 언어 구현만 확인할 수 있습니다.이제 Blowfish는 PHP에서도 사용할 수 있습니다.mcrypt밀번호저 장장장? 떤?? ????복어는 범용 암호로 두 가지 방식으로 작동합니다.암호화할 수 있으면 복호화할 수 있습니다.비밀번호에는 단방향 해시 기능이 필요합니다.

어떤 설명입니까?

bcrypt는 하드웨어로 확장 가능한 해시 알고리즘입니다(설정 가능한 라운드 수에 따라).속도가 느리고 여러 라운드가 이루어지기 때문에 공격자가 암호를 해독하기 위해 막대한 자금과 하드웨어를 배포해야 합니다.패스워드 단위 솔트에 추가(bcrypt소금 필요)를 통해 막대한 자금이나 하드웨어가 없으면 공격이 사실상 불가능하다는 것을 확신할 수 있습니다.

bcryptEksblowfish 알고리즘을 사용하여 비밀번호를 해시합니다.EksblowfishBlowfish의 암호화 단계는 완전히 동일하지만, Eksblowfish의 주요 스케줄 단계는 이후의 상태가 소금과 키(사용자 패스워드) 양쪽에 따라 결정되며, 어느 상태도 둘 다 알지 못하면 미리 계산할 수 없습니다.이 키의 차이로 인해는 단방향 해시 알고리즘입니다.솔트, 라운드(패스워드)를 알고 있지 않으면 일반 텍스트 암호를 검색할 수 없습니다.[출처]

bcrypt 사용방법:

PHP > = 5.5-DEV 사용

이제 암호 해시 기능이 PHP >= 5.5에 직접 내장되었습니다.이제 를 사용하여bcrypt「CHANGE MARGE:」

<?php
// Usage 1:
echo password_hash('rasmuslerdorf', PASSWORD_DEFAULT)."\n";
// $2y$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// For example:
// $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

// Usage 2:
$options = [
  'cost' => 11
];
echo password_hash('rasmuslerdorf', PASSWORD_BCRYPT, $options)."\n";
// $2y$11$6DP.V0nO7YI3iSki4qog6OQI5eiO6Jnjsqg7vdnb.JgGIsxniOn4C

사용자가 입력한 비밀번호를 기존 해시에 대해 확인하려면 다음과 같이 사용할 수 있습니다.

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

PHP > = 5.3.7, < 5.5-DEV (RedHat PHP > = 5.3.3도 사용)

GitHub에는 원래 C로 작성된 위의 함수의 소스 코드를 기반으로 만들어진 호환성 라이브러리가 있으며, 동일한 기능을 제공합니다.호환성 라이브러리가 설치되면 위와 같은 사용법이 됩니다(5.3.x 브랜치에 있는 경우는 생략).

PHP < 5 . 3 . 7 ( DEPRECATED )

하시면 됩니다.crypt()입력 문자열의 bcrypt 해시를 생성하는 함수입니다.이 클래스는 자동으로 소금을 생성하고 입력에 대해 기존 해시를 검증할 수 있습니다.5.3.7 이상의 PHP 버전을 사용하는 경우 내장 함수 또는 호환 라이브러리를 사용하는 것이 좋습니다.이 대안은 과거의 목적으로만 제공됩니다.

class Bcrypt{
  private $rounds;

  public function __construct($rounds = 12) {
    if (CRYPT_BLOWFISH != 1) {
      throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
    }

    $this->rounds = $rounds;
  }

  public function hash($input){
    $hash = crypt($input, $this->getSalt());

    if (strlen($hash) > 13)
      return $hash;

    return false;
  }

  public function verify($input, $existingHash){
    $hash = crypt($input, $existingHash);

    return $hash === $existingHash;
  }

  private function getSalt(){
    $salt = sprintf('$2a$%02d$', $this->rounds);

    $bytes = $this->getRandomBytes(16);

    $salt .= $this->encodeBytes($bytes);

    return $salt;
  }

  private $randomState;
  private function getRandomBytes($count){
    $bytes = '';

    if (function_exists('openssl_random_pseudo_bytes') &&
        (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL is slow on Windows
      $bytes = openssl_random_pseudo_bytes($count);
    }

    if ($bytes === '' && is_readable('/dev/urandom') &&
       ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
      $bytes = fread($hRand, $count);
      fclose($hRand);
    }

    if (strlen($bytes) < $count) {
      $bytes = '';

      if ($this->randomState === null) {
        $this->randomState = microtime();
        if (function_exists('getmypid')) {
          $this->randomState .= getmypid();
        }
      }

      for ($i = 0; $i < $count; $i += 16) {
        $this->randomState = md5(microtime() . $this->randomState);

        if (PHP_VERSION >= '5') {
          $bytes .= md5($this->randomState, true);
        } else {
          $bytes .= pack('H*', md5($this->randomState));
        }
      }

      $bytes = substr($bytes, 0, $count);
    }

    return $bytes;
  }

  private function encodeBytes($input){
    // The following is code from the PHP Password Hashing Framework
    $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $output = '';
    $i = 0;
    do {
      $c1 = ord($input[$i++]);
      $output .= $itoa64[$c1 >> 2];
      $c1 = ($c1 & 0x03) << 4;
      if ($i >= 16) {
        $output .= $itoa64[$c1];
        break;
      }

      $c2 = ord($input[$i++]);
      $c1 |= $c2 >> 4;
      $output .= $itoa64[$c1];
      $c1 = ($c2 & 0x0f) << 2;

      $c2 = ord($input[$i++]);
      $c1 |= $c2 >> 6;
      $output .= $itoa64[$c1];
      $output .= $itoa64[$c2 & 0x3f];
    } while (true);

    return $output;
  }
}

이 코드는 다음과 같이 사용할 수 있습니다.

$bcrypt = new Bcrypt(15);

$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);

또는 Portable PHP Hashing Framework를 사용할 수도 있습니다.

bcrypt를 사용하시겠습니까?대박이다!그러나 다른 암호화 영역과 마찬가지로 사용자가 직접 암호화하면 안 됩니다.키 관리, 염분 저장, 난수 생성과 같은 걱정거리가 필요한 경우, 이는 잘못된 것입니다.

그 이유는 간단하다. 왜냐하면 bcrypt를 망치는 것은 매우 쉽기 때문이다.실제로 이 페이지의 거의 모든 코드를 보면 이러한 일반적인 문제 중 적어도 하나를 위반하고 있음을 알 수 있습니다.

솔직히 말해 암호는 어렵다.

전문가에게 맡기세요.이 라이브러리들을 관리하는 것이 직업인 사람들을 위해 남겨두세요.결정을 내려야 한다면, 그건 잘못하고 있는 거야

대신, 그냥 도서관을 이용하세요.요건에 따라서는 몇 개 존재합니다.

라이브러리

다음은 일반적인 API에 대한 설명입니다.

PHP 5.5 API - (5.3.7+에서 사용 가능)

PHP 5.5부터는 패스워드를 해싱하기 위한 새로운 API가 도입되고 있습니다.또한 5.3.7 이상용으로 유지되는 심 호환성 라이브러리도 있습니다.이는 동료 검토가 가능하고 구현이 간단하다는 장점이 있습니다.

function register($username, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT);
    save($username, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    if (password_verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

정말이지, 이건 아주 단순한 것을 목표로 하고 있어.

자원:

Zend\Crypt\Password\Bcrypt(5.3.2+)

이것은 PHP 5.5와 유사한 또 다른 API로 유사한 목적을 수행합니다.

function register($username, $password) {
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    $hash = $bcrypt->create($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    if ($bcrypt->verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

자원:

패스워드 립

이것은 패스워드 해시에 대한 접근법과는 약간 다릅니다.PasswordLib은 단순히 bcrypt를 지원하는 것이 아니라 다수의 해시 알고리즘을 지원합니다.이 기능은 주로 사용자가 제어할 수 없는 레거시 및 이종 시스템과의 호환성을 지원해야 하는 상황에서 유용합니다.다수의 해시 알고리즘을 지원합니다.또한 5.3.2 이상 지원

function register($username, $password) {
    $lib = new PasswordLib\PasswordLib();
    $hash = $lib->createPasswordHash($password, '$2y$', array('cost' => 12));
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $lib = new PasswordLib\PasswordLib();
    if ($lib->verifyPasswordHash($password, $hash)) {
        //login
    } else {
        // failure
    }
}

참고 자료:

  • 소스 코드/문서: GitHub

패스

이 계층은 bcrypt를 지원하지만 PHP > = 5.3.2에 액세스할 수 없는 경우에 유용한 매우 강력한 알고리즘도 지원합니다.실제로 PHP 3.0+를 지원합니다(bcrypt는 지원하지 않습니다).

function register($username, $password) {
    $phpass = new PasswordHash(12, false);
    $hash = $phpass->HashPassword($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $phpass = new PasswordHash(12, false);
    if ($phpass->CheckPassword($password, $hash)) {
        //login
    } else {
        // failure
    }
}

자원.

주의: 오픈월에서 호스트되지 않은 PHPASS 대체품을 사용하지 마십시오.이것들은 다른 프로젝트입니다.

BCrypt에 대해서

이러한 라이브러리는 모두 하나의 문자열을 반환합니다.그것은 BCrypt가 내부적으로 작동하는 방식 때문입니다.그리고 그것에 대한 수많은 답변들이 있다.여기에서는 복사/붙여넣기를 하지 않고 다음 링크에 접속할 수 있는 선택사항이 있습니다.

정리

여러 가지 선택지가 있습니다.당신이 선택하는 것은 당신에게 달렸어요., 위의 라이브러리 중 하나를 사용하는 것이 좋습니다.

다시 말씀드리지만crypt()가 를 사용하고 경우hash() (오류)md5() ★★★★★★★★★★★★★★★★★」sha1())직접적으로, 당신은 거의 틀림없이 뭔가 잘못된 일을 하고 있습니다.

그냥 도서관을 이용하면...

레인보우 테이블로 충분한 정보를 얻을 수 있습니다. 보안 비밀번호 체계 또는 Portable PHP 비밀번호 해시 프레임워크에 대해 알아야사항

패스워드를 느린 것으로 해시하는 것이 목적입니다.따라서 패스워드 데이터베이스를 취득한 누군가가 패스워드를 강제하려고 하면 사망합니다(패스워드를 확인하는 데 10밀리초의 지연은 당신에게는 아무것도 아닙니다.비밀번호를 강제하려고 하는 사람에게는 매우 큰 지연입니다).Bcrypt는 느리고 파라미터와 함께 사용하여 얼마나 느린지 선택할 수 있습니다.

PHP를 사용하여 bcrypt를 수 .crypt()적절한 복어소금을 공급한다.전체 방정식 중 가장 중요한 것은 A) 알고리즘이 손상되지 않았으며 B) 각 비밀번호를 적절하게 소금에 절인다는 입니다.어플리케이션 전체의 salt를 사용하지 마십시오.그러면 어플리케이션 전체가 하나의 Rainbow 테이블 세트에서 공격을 받을 수 있습니다.

PHP - 암호화 함수


편집: 2013.01.15 - 서버가 지원하는 경우 대신 martinstockli의 솔루션을 사용하십시오.


모든 사람들이 이걸 더 복잡하게 만들고 싶어해.대부분의 작업은 crypt() 함수가 수행합니다.

function blowfishCrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2y$%02d$',$cost);
//For PHP < PHP 5.3.7 use this instead
//    $salt=sprintf('$2a$%02d$',$cost);
    //Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand
    mt_srand();
    for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)];
    return crypt($password,$salt);
}

예를 들어:

$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password

당연한 거 알지만 비밀번호로 '비밀번호'를 사용하지 마세요.

버전 5.5의 PHP는 BCrypt, 함수 및 를 기본적으로 지원합니다.실제로 이들은 함수 주위에 있는 래퍼일 뿐이므로 올바르게 사용하기 쉬워집니다.안전한 랜덤 소금의 생성을 처리하고 좋은 기본값을 제공합니다.

이 기능을 사용하는 가장 쉬운 방법은 다음과 같습니다.

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

)로 .2y 파라미터는 10)를 사용합니다.두 번째 행은 사용자가 입력한 암호가 이미 저장된 해시 값과 일치하는지 확인합니다.

비용 파라미터를 변경할 경우 다음과 같이 변경할 수 있습니다.비용 파라미터를 1씩 늘리면 해시값을 계산하는 데 필요한 시간이 2배로 늘어납니다.

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11));

와와 the the the the the in와는 "cost"."salt"이 함수는 이미 암호학적으로 안전한 소금을 생성하기 위해 최선을 다하고 있기 때문입니다.

PHP 버전 5.3.7 이후의 경우 호환성 팩이 존재하며, 이 팩을 만든 필자가password_hash()이전 에서는 5.3.7 PHP는 지원되지 않습니다.crypt()2y safe 알고리즘 Unicode safe BCrypt " " 입니다. '아까보다'로 요.2a이전 버전의 PHP를 대체하는 가장 좋은 방법입니다.

현재의 생각: 해시는 가장 느린 것이어야 하며, 가장 빠른 것이어야 합니다.무지개 테이블 공격을 억제합니다.

관련성이 있지만 주의사항:공격자는 로그인 화면에 무제한으로 액세스 할 수 없습니다.이를 방지하려면 URI와 함께 모든 히트를 기록하는 IP 주소 추적 테이블을 설정합니다. 5분 동안 동일한 IP 주소에서 로그인을 5회 이상 시도할 경우 설명을 포함하여 차단하십시오.두 번째 접근법은 은행과 마찬가지로 2계층 패스워드 방식을 사용하는 것입니다.세컨드 패스의 장애에 대한 록아웃을 실시하면 보안이 강화됩니다.

요약: 시간이 많이 걸리는 해시 함수를 사용하여 공격자의 속도를 늦춥니다.또한 로그인에 대한 너무 많은 액세스를 차단하고 두 번째 암호 계층을 추가합니다.

여기 이 오래된 질문에 대한 업데이트된 답변이 있습니다!

5.5 이후 PHP에서 패스워드를 해시하는 올바른 방법은 를 사용하는 것입니다.또한 패스워드를 검증하는 올바른 방법은 를 사용하는 것입니다.PHP 8.0에서도 마찬가지입니다.이러한 함수는 기본적으로 bcrypt 해시를 사용하지만 다른 강력한 알고리즘이 추가되었습니다.워크팩터(암호화의 '강력한' 정도)를 변경할 수 있습니다.password_hash파라미터를 지정합니다.

그러나 아직 충분히 강력하지만 bcrypt는 더 이상 최신 기술로 간주되지 않습니다. Argon2i, Argon2d 및 Argon2id 변종과 함께 Argon2라는 더 나은 암호 해시 알고리즘 세트가 출시되었습니다.그 차이는 다음과 같습니다(여기서 설명하겠습니다.

Argon2에는 1개의 주요 배리언트가 있습니다.Argon2id 및 다음 두 가지 보조 변종:Argon2d 및 Argon2i.Argon2d는 데이터 의존형 메모리 액세스를 사용해 사이드 채널 타이밍 공격의 위협 없이 가상화폐 및 작업 증명 애플리케이션에 적합하다.Argon2i는 데이터에 의존하지 않는 메모리액세스를 사용합니다.이는 패스워드 해싱 및 패스워드 기반 키 도출에 적합합니다.Argon2id는 메모리를 통한 첫 번째 반복의 전반에는 Argon2i로 기능하고 나머지에는 Argon2d로 기능합니다.따라서 시간 메모리 트레이드오프에 의한 사이드 채널 공격 보호와 브루트포스 비용 절감이 모두 실현됩니다.

Argon2i 지원은 PHP 7.2에서 추가되었으며 다음과 같이 요청하면 됩니다.

$hash = password_hash('mypassword', PASSWORD_ARGON2I);

및 Argon2id 지원이 PHP 7.3에 추가되었습니다.

$hash = password_hash('mypassword', PASSWORD_ARGON2ID);

생성된 해시 문자열에는 생성 시 사용된 알고리즘, 솔트 및 작업 계수에 대한 정보가 포함되므로 비밀번호 확인에는 변경이 필요하지 않습니다.

상당히 별개로 (그리고 다소 장황하게) libsodium(PHP 7.2에 추가)은 및 함수를 통해 Argon2 해시를 제공합니다.이러한 해시는 PHP 빌트인과 거의 동일한 방식으로 작동합니다.PHP를 사용하는 이유 중 하나는 password_hash 함수가 Argon2 알고리즘을 사용할 수 없게 만드는 경우가 있기 때문입니다.PHP 7.2 이상에서는 항상 libsodium을 사용할 수 없지만 적어도 두 가지 방법이 있습니다.Libsodium을 사용하여 Argon2id 해시를 작성하는 방법은 다음과 같습니다(PHP 7.2에서도 마찬가지이며, 그렇지 않으면 Argon2id 지원이 없습니다).

$hash = sodium_crypto_pwhash_str(
    'mypassword',
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

솔트를 수동으로 지정할 수 없습니다.이것은 Libsodium의 정신의 일부입니다.예를 들어 사용자가 보안을 해칠 수 있는 값에 파라미터를 설정하는 것을 허용하지 마십시오.예를 들어 빈 솔트 문자열을 PHP에 전달하는 것을 방해하는 것은 없습니다.password_hash기능성; 립소듐은 그런 바보 같은 짓은 못하게 해!

OAuth 2 비밀번호의 경우:

$bcrypt = new \Zend\Crypt\Password\Bcrypt;
$bcrypt->create("youpasswordhere", 10)

아시다시피 비밀번호를 클리어 텍스트로 데이터베이스에 저장하는 것은 안전하지 않습니다.bcrypt는 해시 패스워드 기술입니다.비밀번호 보안을 구축하는 데 사용됩니다.bcrypt의 놀라운 기능 중 하나는 암호는 bcrypt 형식으로 저장되기 때문에 해킹 공격으로부터 암호를 보호하는 데 사용됩니다.

password_hash()함수는 새로운 비밀번호 해시를 작성하기 위해 사용됩니다.강력하고 견고한 해시 알고리즘을 사용합니다.password_hash()는 이 함수와 .crypt()는 에 의해 작성됩니다.crypt() 함께 할 수 .password_hash()그리고 부차관.password_verify() ★★★★★★★★★★★★★★★★★」password_hash() 만.crypt()이데올로기 때문에

구문

string password_hash($password, $algo, $options)

되고 있습니다.password_hash()★★★★

  • PASSWORD_DEFAULT
  • PASSWORD_BCRYPT
  • PASSWORD_ARGON2I
  • PASSWORD_ARGON2ID

파라미터:이 함수는 위에서 설명한 바와 같이 아래 설명된 세 가지 파라미터를 받아들입니다.

$password 사용자의 패스워드가 저장됩니다.

$algo: 해시가 할 때 지속적으로 비밀번호 해시가 발생할 때 사용하는 알고리즘을 나타내면서 지속적으로 사용하는 비밀번호 알고리즘 상수입니다.

$options: 된 연관 옵션이 포함된 연관 배열입니다.이것이 삭제되고 포함되지 않으면 랜덤 솔트가 사용되며 디폴트비용이 사용됩니다.

Return Value: 성공 시 해시된 비밀번호를 반환하고 실패 시 False를 반환합니다.

:

입력:

echo password_hash("GFG@123", PASSWORD_DEFAULT);

출력:

$2y$10$.vGA19Jh8YrwSJFDodbfoHJIOFH)DfhuofGv3Fykk1a

은 below음음 below below below below below 。password_hash()PHP:

<?php echo password_hash("GFG@123", PASSWORD_DEFAULT); ?>

산출량

$2y$10$Z166W1fBdsLcXPVQVfPw/uRq1ueWMA6sLt9bmdUFz9AmOGLdM393G

password_hash()PHP의 함수는 다른 알고리즘과 옵션을 사용하여 새로운 비밀번호 해시를 만드는 데 사용되는 내장 함수입니다.이 함수는 강력한 해시 알고리즘을 사용합니다.

는 2개의 즉 '이러다'를 합니다.$password ★★★★★★★★★★★★★★★★★」$algorithm "1 " " " " " "$options.

$strongPassword = password_hash( $password, $algorithm, $options );

은 지금 할 수 있습니다.password_hash()과 같습니다

  • PASSWORD_DEFAULT
  • PASSWORD_BCRYPT
  • PASSWORD_ARGON2I
  • PASSWORD_ARGON2ID

예를 들어:

echo password_hash("abcDEF", PASSWORD_DEFAULT);

답변:

$2y$10$KwKceUaG84WInAif5ehdZOkE4kHPWTLp0ZK5a5OU2EbtdwQ9YIcGy

예를 들어:

echo password_hash("abcDEF", PASSWORD_BCRYPT);

답변:

$2y$10$SNly5bFzB/R6OVbBMq1bj.yiOZdsk6Mwgqi4BLR2sqdCvMyv/AyL2

「 」를 BCRYPT option , set 옵 ,cost=12 an $options 파라미터도 $password로 변환합니다."wgt167yuWBGY@#1987__".

예를 들어:

echo password_hash("wgt167yuWBGY@#1987__", PASSWORD_BCRYPT, ['cost' => 12]);

답변:

$2y$12$TjSggXiFSidD63E.QP8PJOds2texJfsk/82VaNU8XRZ/niZhzkJ6S

언급URL : https://stackoverflow.com/questions/4795385/how-do-you-use-bcrypt-for-hashing-passwords-in-php

반응형