양방향 암호화 : 검색 할 수있는 비밀번호를 저장해야합니다


174

사용자가 검색하고 볼 수있는 비밀번호를 저장할 애플리케이션을 작성 중입니다. 암호는 하드웨어 장치 용이므로 해시 확인은 문제가되지 않습니다.

내가 알아야 할 것은 :

  1. PHP에서 암호를 어떻게 암호화하고 해독합니까?

  2. 비밀번호를 암호화하는 가장 안전한 알고리즘은 무엇입니까?

  3. 개인 키는 어디에 저장합니까?

  4. 개인 키를 저장하는 대신 암호를 해독해야 할 때마다 사용자가 개인 키를 입력하도록 요구하는 것이 좋습니다. (이 응용 프로그램의 사용자는 신뢰할 수 있습니다)

  5. 비밀번호를 도난 및 해독 할 수있는 방법은 무엇입니까? 무엇을 알고 있어야합니까?


1
참고 : Libsodium은 이제 == 7.2를 위해 PHP 코어로 컴파일되었습니다. 더 이상 사용되지 않는 것으로 간주되어 제거 된 mcrypt와는 달리 최신 방법으로 가득 차 있으므로 "이동"솔루션입니다.
Exhibitioner

답변:


212

개인적으로 mcrypt다른 사람들이 게시 한 것처럼 사용 합니다. 그러나 주목할 것이 훨씬 더 많습니다 ...

  1. PHP에서 암호를 어떻게 암호화하고 해독합니까?

    당신을 위해 모든 것을 돌보는 강력한 수업은 아래를 참조하십시오.

  2. 비밀번호를 암호화하는 가장 안전한 알고리즘은 무엇입니까?

    가장 안전한 가요? 그들 중 하나. 암호화하려는 경우 가장 안전한 방법은 정보 유출 취약성 (XSS, 원격 포함 등)을 방지하는 것입니다. 그것이 유출되면 공격자는 결국 암호화를 해독 할 수 있습니다 (키없이 암호화를 되돌릴 수없는 100 %는 없습니다-@NullUserException이 지적한 것처럼 이것은 완전히 사실이 아닙니다. OneTimePad 와 같이 해독이 불가능한 일부 암호화 체계가 있습니다 ) .

  3. 개인 키는 어디에 저장합니까?

    내가 할 일은 3 키를 사용하는 것입니다. 하나는 사용자가 제공하고 다른 하나는 응용 프로그램에 따라 다른 하나는 소금과 같은 사용자에 따라 다릅니다. 응용 프로그램 특정 키는 웹 루트 외부의 환경 설정 파일, 환경 변수 등 어디에나 저장할 수 있습니다. 사용자 별 암호는 암호화 된 암호 옆에있는 DB의 열에 저장됩니다. 사용자가 제공 한 것이 저장되지 않았습니다. 그런 다음 다음과 같은 작업을 수행합니다.

    $key = $userKey . $serverKey . $userSuppliedKey;

    이로 인한 이점은 데이터를 손상시키지 않고 2 개의 키를 손상시킬 수 있다는 것입니다. SQL 주입 공격이 있다면, 그들은을 얻을 수 $userKey있지만, 다른 2 로컬 서버가 악용이 있다면, 그들이 얻을 수 $userKey하고 $serverKey있지만, 셋째 없습니다 $userSuppliedKey. 그들이 렌치로 사용자를 이길 경우 $userSuppliedKey다른 2를 얻을 수는 없지만 다시 얻을 수는 있습니다 (그러나 다시 사용자가 렌치로 맞으면 너무 늦습니다).

  4. 개인 키를 저장하는 대신 암호를 해독해야 할 때마다 사용자가 개인 키를 입력하도록 요구하는 것이 좋습니다. (이 응용 프로그램의 사용자는 신뢰할 수 있습니다)

    물론. 사실, 내가 할 유일한 방법입니다. 그렇지 않으면 암호화되지 않은 버전을 내구성있는 저장소 형식 (APC 또는 memcached와 같은 공유 메모리 또는 세션 파일)으로 저장해야합니다. 그것은 추가 타협에 노출됩니다. 암호화되지 않은 암호 버전을 로컬 변수 이외의 다른 곳에 저장하지 마십시오.

  5. 비밀번호를 도난 및 해독 할 수있는 방법은 무엇입니까? 무엇을 알고 있어야합니까?

    시스템이 손상되면 암호화 된 데이터를 볼 수 있습니다. 코드를 삽입하거나 파일 시스템에 액세스 할 수있는 경우 해독 된 데이터를 볼 수 있습니다 (데이터를 해독하는 파일을 편집 할 수 있으므로). 모든 형태의 Replay 또는 MITM 공격도 관련된 키에 대한 모든 액세스 권한을 부여합니다. 원시 HTTP 트래픽을 스니핑하면 키가 제공됩니다.

    모든 트래픽에 SSL을 사용하십시오. 그리고 서버에 어떤 종류의 취약점 (CSRF, XSS, SQL Injection, Privilege Escalation, Remote Code Execution 등)이 없는지 확인하십시오.

편집 : 강력한 암호화 방법의 PHP 클래스 구현은 다음과 같습니다.

/**
 * A class to handle secure encryption and decryption of arbitrary data
 *
 * Note that this is not just straight encryption.  It also has a few other
 *  features in it to make the encrypted data far more secure.  Note that any
 *  other implementations used to decrypt data will have to do the same exact
 *  operations.  
 *
 * Security Benefits:
 *
 * - Uses Key stretching
 * - Hides the Initialization Vector
 * - Does HMAC verification of source data
 *
 */
class Encryption {

    /**
     * @var string $cipher The mcrypt cipher to use for this instance
     */
    protected $cipher = '';

    /**
     * @var int $mode The mcrypt cipher mode to use
     */
    protected $mode = '';

    /**
     * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
     */
    protected $rounds = 100;

    /**
     * Constructor!
     *
     * @param string $cipher The MCRYPT_* cypher to use for this instance
     * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
     * @param int    $rounds The number of PBKDF2 rounds to do on the key
     */
    public function __construct($cipher, $mode, $rounds = 100) {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->rounds = (int) $rounds;
    }

    /**
     * Decrypt the data with the provided key
     *
     * @param string $data The encrypted datat to decrypt
     * @param string $key  The key to use for decryption
     * 
     * @returns string|false The returned string if decryption is successful
     *                           false if it is not
     */
    public function decrypt($data, $key) {
        $salt = substr($data, 0, 128);
        $enc = substr($data, 128, -64);
        $mac = substr($data, -64);

        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) {
             return false;
        }

        $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

        $data = $this->unpad($dec);

        return $data;
    }

    /**
     * Encrypt the supplied data using the supplied key
     * 
     * @param string $data The data to encrypt
     * @param string $key  The key to encrypt with
     *
     * @returns string The encrypted data
     */
    public function encrypt($data, $key) {
        $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        $data = $this->pad($data);

        $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

        $mac = hash_hmac('sha512', $enc, $macKey, true);
        return $salt . $enc . $mac;
    }

    /**
     * Generates a set of keys given a random salt and a master key
     *
     * @param string $salt A random string to change the keys each encryption
     * @param string $key  The supplied key to encrypt with
     *
     * @returns array An array of keys (a cipher key, a mac key, and a IV)
     */
    protected function getKeys($salt, $key) {
        $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
        $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
        $length = 2 * $keySize + $ivSize;

        $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

        $cipherKey = substr($key, 0, $keySize);
        $macKey = substr($key, $keySize, $keySize);
        $iv = substr($key, 2 * $keySize);
        return array($cipherKey, $macKey, $iv);
    }

    /**
     * Stretch the key using the PBKDF2 algorithm
     *
     * @see http://en.wikipedia.org/wiki/PBKDF2
     *
     * @param string $algo   The algorithm to use
     * @param string $key    The key to stretch
     * @param string $salt   A random salt
     * @param int    $rounds The number of rounds to derive
     * @param int    $length The length of the output key
     *
     * @returns string The derived key.
     */
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
        $size   = strlen(hash($algo, '', true));
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
            $res = $tmp;
            for ($j = 1; $j < $rounds; $j++) {
                 $tmp  = hash_hmac($algo, $tmp, $key, true);
                 $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

    protected function pad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $padAmount = $length - strlen($data) % $length;
        if ($padAmount == 0) {
            $padAmount = $length;
        }
        return $data . str_repeat(chr($padAmount), $padAmount);
    }

    protected function unpad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $last = ord($data[strlen($data) - 1]);
        if ($last > $length) return false;
        if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
            return false;
        }
        return substr($data, 0, -1 * $last);
    }
}

PHP 5.6 :에 추가 된 함수를 사용하고 있습니다 hash_equals. 5.6보다 낮 으면 이중 HMAC 검증을 사용하여 타이밍 안전 비교 기능 을 구현하는이 대체 기능을 사용할 수 있습니다 .

function hash_equals($a, $b) {
    $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}

용법:

$e = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$encryptedData = $e->encrypt($data, $key);

그런 다음 해독하십시오.

$e2 = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$data = $e2->decrypt($encryptedData, $key);

$e2다른 인스턴스가 데이터를 올바르게 해독한다는 것을 보여주기 위해 두 번째로 사용 했습니다.

이제 어떻게 작동합니까? 왜 다른 솔루션보다 사용합니까?

  1. 열쇠

    • 키는 직접 사용되지 않습니다. 대신, 키는 표준 PBKDF2 파생으로 확장됩니다.

    • 암호화에 사용되는 키는 암호화 된 모든 텍스트 블록에 고유합니다. 제공된 키는 "마스터 키"가됩니다. 따라서이 클래스는 암호 및 인증 키에 대한 키 회전을 제공합니다.

    • 중요 사항 :이 $rounds매개 변수는 충분한 강도의 실제 임의 키 (최소 128 비트 암호화 보안 임의)로 구성됩니다. 암호 또는 비 랜덤 키 (또는 임의의 128 비트 CS 랜덤보다 적은 임의의 키)를 사용하려는 경우이 매개 변수 늘려야합니다. 나는 암호에 대해 최소 10000을 제안 할 것입니다 (당신이 감당할수록 더 좋을지라도 런타임에 추가 될 것입니다 ...)

  2. 데이터 무결성

    • 업데이트 된 버전은 ENCRYPT-THEN-MAC를 사용하는데, 이는 암호화 된 데이터의 신뢰성을 보장하는 훨씬 더 좋은 방법입니다.
  3. 암호화 :

    • mcrypt를 사용하여 실제로 암호화를 수행합니다. 하나 MCRYPT_BLOWFISH또는 MCRYPT_RIJNDAEL_128사이퍼 MCRYPT_MODE_CBC를 사용하고 모드를 사용하는 것이 좋습니다 . 그것은 충분히 강력하고 여전히 빠릅니다 (암호화 및 암호 해독주기는 내 컴퓨터에서 약 1/2 초가 걸립니다).

이제 첫 번째 목록에서 3을 가리키면 다음과 같은 기능이 제공됩니다.

function makeKey($userKey, $serverKey, $userSuppliedKey) {
    $key = hash_hmac('sha512', $userKey, $serverKey);
    $key = hash_hmac('sha512', $key, $userSuppliedKey);
    return $key;
}

makeKey()함수 에서 확장 할 수는 있지만 나중에 확장 될 것이기 때문에 실제로 그렇게 큰 포인트는 없습니다.

저장 크기까지는 일반 텍스트에 따라 다릅니다. Blowfish는 8 바이트 블록 크기를 사용하므로 다음과 같은 이점이 있습니다.

  • 소금은 16 바이트
  • hmac의 경우 64 바이트
  • 데이터 길이
  • 데이터 길이 % 8 == 0이되도록 채우기

따라서 16 자 데이터 소스의 경우 16 자 데이터가 암호화됩니다. 따라서 실제 암호화 된 데이터 크기는 패딩으로 인해 16 바이트입니다. 그런 다음 salt에 16 바이트를 추가하고 hmac에 64 바이트를 추가하면 총 저장 크기는 96 바이트입니다. 따라서 최대 80 자의 오버 헤드가 발생하고 최악의 경우 87 자의 오버 헤드가 발생합니다.

도움이되기를 바랍니다 ...

참고 : 12/11/12 : 방금 더 나은 파생 키를 사용하고 MAC 생성을 수정하는 훨씬 나은 암호화 방법 으로이 클래스를 업데이트했습니다 ...


3
누군가 그것이 "휴식"의 의미를 이해하지 못합니다. 수업에서 @IRC 좋은 일, 그것은 꽤 저주 좋은 코드입니다.
jcolebrand

1
다음은 false를 반환합니다. 왜 그런지 알아? $ x = 새로운 암호화 (MCRYPT_BlOWFISH, MCRYPT_MODE_CBC); $ test = $ x-> encrypt ( "test", "a"); echo var_dump ($ x-> decrypt ($ test, "a"));
파장

2
아, 그리고 다시이 개 변경 해독 기능에 -64에들 -128경우 도왔습니다 (그래서 $enc = substr($data, 128, -128)$mac = substr($data, -128);
cosmorogers

4
@ircmaxell 코드가 마지막으로 수정 된 이후 꽤 오래되었으므로 최신인지 궁금합니다. 나는 금융 응용 프로그램에 비슷한 것을 사용해야
하며이

2
경고! mcrypt 확장 기능은 현재 거의 10 년 동안 버려졌으며 사용하기도 상당히 복잡했습니다. 따라서 OpenSSL을 위해 더 이상 사용되지 않으며 PHP 7.2에서는 코어에서 PECL로 제거됩니다. th1.php.net/manual/en/migration71.deprecated.php
vee

15

PHP에서 암호를 어떻게 암호화하고 해독합니까? 많은 암호화 알고리즘 중 하나를 구현합니다. (또는 많은 라이브러리 중 하나를 사용)

비밀번호를 암호화하는 가장 안전한 알고리즘은 무엇입니까? 다양한 알고리즘이 있으며 100 % 안전하지는 않습니다. 그러나 이들 중 다수는 상업 및 군사 목적으로도 충분히 안전합니다.

개인 키는 어디에 저장합니까? 공개 키-암호화 알고리즘 (예 : RSA)을 구현하기로 결정한 경우 개인 키를 저장하지 않습니다. 사용자는 개인 키를 가지고 있습니다. 시스템에는 원하는 곳에 저장할 수있는 공개 키가 있습니다.

개인 키를 저장하는 대신 암호를 해독해야 할 때마다 사용자가 개인 키를 입력하도록 요구하는 것이 좋습니다. (이 응용 프로그램의 사용자는 신뢰할 수 있습니다.) 사용자가 엄청나게 긴 소수를 기억할 수 있다면-그렇습니다. 그러나 일반적으로 사용자는 키를 어딘가에 저장할 수있는 시스템을 고안해야합니다.

비밀번호를 도난 및 해독 할 수있는 방법은 무엇입니까? 무엇을 알고 있어야합니까? 이것은 사용 된 알고리즘에 따라 다릅니다. 그러나 항상 암호화되지 않은 비밀번호를 사용자에게 보내거나 사용자에게 보내지 마십시오. 클라이언트 쪽에서 암호화 / 암호 해독하거나 https (또는 사용자의 다른 암호화 수단을 사용하여 서버와 클라이언트 간의 연결을 보호)하십시오.

그러나 암호를 암호화 된 방식으로 저장하기 만하면 간단한 XOR 암호를 사용하는 것이 좋습니다. 이 알고리즘의 주된 문제점은 주파수 분석에 의해 쉽게 깨질 수 있다는 것입니다. 그러나 일반적으로 암호는 영어 텍스트의 긴 단락으로 만들어지지 않으므로 걱정할 필요가 없다고 생각합니다. XOR 암호의 두 번째 문제점은 암호화 된 형식과 암호 해독 된 형식의 메시지가있는 경우 암호화 된 암호를 쉽게 찾을 수 있다는 것입니다. 다시 말하지만, 다른 방법으로 이미 손상된 사용자에게만 영향을 미치기 때문에 큰 문제는 아닙니다.


답변 3에서 사용자에게 개인 키가 있다고 말하면 그 의미를 이해할 수 없습니다. 사용자가 개인 키를 응용 프로그램에 수동으로 전달하지 않는 것이 좋습니다. 개인 키는 응용 프로그램에 어떻게 전달됩니까?
HyderA

글쎄, 그것은 약간의 문제입니다. 개인 키는 텍스트 파일에 저장 한 다음 앱에 복사하여 붙여 넣을 수 있습니다. 키는 서버에 저장 될 수도 있지만이 경우 XOR과 같은 다른 암호화 알고리즘으로 암호화되어야합니다. 이 경우 XOR을 사용하면 암호 메시지 쌍이 하나만 있고 메시지가 매우 임의이므로 주파수 분석 콜드를 사용하지 않으므로 충분히 안전합니다.
Ivan

4
암호화 알고리즘을 직접 구현하는 것은 권장하지 않으며 잠재적 인 함정이 너무 많으며 기존 라이브러리를 많은 사람들이 테스트하고 분석했습니다.
Long Ears

XOR의 주요 문제점은 누군가가 애플리케이션 데이터를 훔치고 사용자 비밀번호 중 하나만 알고 있으면 해당 사용자의 다른 모든 비밀번호를 해독 할 수 있다는 것입니다.
긴 귀

1
@Ivan : 그렇습니다. 그러나 암호를 완전히 이해하지 않으면 DIY가 정말 나쁜 것으로 생각되는 경우 중 하나입니다 . 존재하는 강력한 암호가 있는데 왜 사용하지 않습니까?
ircmaxell

13
  1. 당신이 따르는 PHP 기능은 Mcrypt ( http://www.php.net/manual/en/intro.mcrypt.php )입니다.

이 예제에서 매뉴얼의 예제는 약간 편집되었습니다.

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$pass = "PasswordHere";
echo strlen($pass) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $pass, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
?>

mcrypt_decrypt 를 사용 하여 비밀번호를 해독합니다.

  1. 가장 좋은 알고리즘 은 주관적입니다. 5 명에게 물어보고 5 명 답변하십시오. 개인적으로 기본값 (Blowfish)이 충분하지 않으면 더 큰 문제가있을 것입니다!

  2. PHP에서 암호화가 필요하다는 점을 감안할 때 (어디서나 숨길 수는 없지만) 이에 대한 의견을 환영합니다. 물론 표준 PHP 베스트 코딩 방법이 적용됩니다!

  3. 어쨌든 암호화 키가 코드에 포함되어 있다고 가정하면 나머지 응용 프로그램이 안전한 경우 얻을 수있는 것이 무엇인지 확실하지 않습니다.

  4. 암호화 된 암호와 암호화 키를 도난당한 경우 게임 오버가됩니다.

나는 내 대답에 라이더를 뒀다. 나는 PHP 암호 전문가가 아니지만, 내가 대답 한 것은 표준 관행이라고 생각한다-다른 사람들이 할 수있는 의견을 환영한다.


$pass = $text. 나는 그가 그 질문에 부응하기 위해 그것을 바꿨고 두 번째 사건을 보지 못했다고 생각합니다.
HyderA

3
두 가지 유의할 사항. 먼저 MCRYPT_MODE_ECBIV를 사용하지 않습니다. 둘째, 데이터가 없으면 데이터를 해독 할 수 없으므로 IV를 저장해야합니다.
ircmaxell

"최고의 알고리즘은 다소 주관적입니다. 5 명에게 질문하고 5 개의 답변을 받으십시오. 개인적으로 기본 (Blowfish)이 충분하지 않으면 더 큰 문제가있을 수 있습니다." 이것은 완전히 잘못되었습니다. 모든 암호 전문가는 것이다 다소간에 동의 gist.github.com/tqbf/be58d2d39690c3b366ad 특별히 제외는 복어하는
스콧 Arciszewski

6

많은 사용자가 mcrypt 사용을 제안했습니다 ... 정확하지만 쉽게 저장하고 전송할 수 있도록 한 단계 더 나아가고 싶습니다 (때때로 암호화 된 값은 curl 또는 json과 같은 다른 기술을 사용하여 전송하기가 어려울 수 있기 때문에) .

mcrypt를 사용하여 성공적으로 암호화 한 후 base64_encode를 통해 실행 한 다음 16 진 코드로 변환하십시오. 16 진수 코드로 다양한 방법으로 쉽게 전송할 수 있습니다.

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $unencrypted);
$encrypted = $ua."||||".$iv;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$encrypted = base64_encode($encrypted);
$encrypted = array_shift(unpack('H*', $encrypted));

그리고 다른쪽에는 :

$encrypted = pack('H*', $encrypted);
$encrypted = base64_decode($encrypted);
list($encrypted,$iv) = explode("||||",$encrypted,2);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$unencrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);


2
글쎄-그것은 2011 년이었다 : P
Bradley

5

상호 작용없이 사용자 암호를 설정하려는 경우에만 공개 키 암호화를 제안합니다 (재설정 및 공유 암호에 유용 할 수 있음).

공개 키

  1. OpenSSL 부호 확장 구체적 openssl_public_encryptopenssl_private_decrypt
  2. 암호가 키 크기 (패딩)에 적합하다고 가정하면 RSA가 간단합니다.
  3. 각 사용자에 대한 두 키를 저장하십시오. 개인 키의 암호는 응용 프로그램 암호입니다

대칭

  1. Mcrypt 라이브러리의 확장
  2. AES-256은 아마도 안전한 내기이지만, 그 자체로는 SO 질문 일 수 있습니다.
  3. 당신은하지 않습니다-이것은 그들의 응용 프로그램 암호입니다

양자 모두

4. 예-사용자는 매번 애플리케이션 비밀번호를 입력해야하지만 세션에 저장하면 다른 문제가 발생합니다.

5.

  • 누군가가 응용 프로그램 데이터를 훔치는 경우 대칭 암호만큼 안전합니다 (공개 키 체계의 경우 암호로 개인 키를 보호하는 데 사용됩니다).
  • 클라이언트 인증서를 사용하여 SSL을 통해서만 응용 프로그램에 액세스 할 수 있어야합니다.
  • SMS를 통해 전송되는 토큰과 같이 세션 당 한 번만 사용되는 인증에 두 번째 요소를 추가하십시오.

mcrypt를 피하십시오 openssl_private_decrypt().에 주의하십시오 .
Scott Arciszewski 8:15에

2

나는 이것과 같은 것을 시도했지만 암호 작성자가 아니며 php프로그래밍 언어에 대한 심층적 인 지식을 가지고 있지 않습니다 . 아이디어 일뿐입니다. 내 생각은 key일부 파일 에 저장 database하거나 수동으로 입력하여 위치를 쉽게 예측할 수 없으며 (물론 언젠가는 암호 해독 시간을 연장하는 개념입니다) 민감한 정보를 암호화하는 것입니다.

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "myemail@domain.com";
echo "Key : ".$key."<br/>";
echo "Text : ".$text . "<br/>";
echo "Md5 : ".md5($text). "<br/>";
echo "Sha1 : ".sha1($text). "<br/>";



$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH , $key, $text, MCRYPT_MODE_ECB, $iv);
echo "Crypted Data : ".$crypttext."<br>";

$base64 = base64_encode($crypttext);
echo "Encoded Data : ".$base64."<br/>";
$decode =  base64_decode($base64);


$decryptdata = mcrypt_decrypt(MCRYPT_BLOWFISH , $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Decoded Data : ".ereg_replace("?", null ,  $decryptdata); 
//event if i add '?' to the sting to the text it works, I don't know why.

단지 개념 일뿐입니다. 이 코드의 개선은 대단히 감사 할 것입니다.


2

암호는 하드웨어 장치 용이므로 해시 확인은 문제가되지 않습니다.

뭐라고? 이해가 안 돼요 비밀번호를 복구 할 수 있어야한다는 의미입니까?

다른 사람들이 말했듯이, mcrypt 확장 기능은 많은 암호화 기능에 대한 액세스를 제공합니다. 그러나 사용자는 모든 달걀을 한 바구니에 넣을 수 있습니다-잠재적으로 공격자의 대상이 될 것입니다. 문제 해결을 시작하는 방법은 다음과 같습니다. 데이터 보호 방법을 이해할 수있는 위치에 있지 않습니다.

대부분의 보안 취약점은 기본 알고리즘에 결함이 있거나 안전하지 않기 때문에가 아니라 응용 프로그램 코드 내에서 알고리즘이 사용되는 방식에 문제가 있기 때문에 발생합니다.

그렇게 말하면 가능합니다 합리적으로 보안 시스템을 구축 할 수 있습니다.

사용자가 다른 (특정) 사용자가 읽을 수있는 보안 메시지를 작성해야하는 경우에만 비대칭 암호화를 고려해야합니다. 그 이유는 계산 비용이 많이 들기 때문입니다. 사용자가 자신의 데이터를 입력하고 검색 할 수 있도록 리포지토리를 제공하려는 경우 대칭 암호화가 적합합니다.

그러나 암호화 된 메시지와 동일한 위치 (또는 암호화 된 메시지가 저장된 위치)에 메시지 암호 해독 키를 저장하면 시스템이 안전하지 않습니다. 사용자를 인증하는 데 암호 해독 키와 동일한 토큰을 사용하십시오 (또는 비대칭 암호화의 경우 토큰을 개인 키 암호 문구로 사용하십시오). 암호 해독이 최소한 일시적으로 발생하는 서버에 토큰을 저장해야하므로 검색 할 수없는 세션 저장소 인쇄물을 사용하거나 토큰을 저장할 세션과 연결된 데몬에 직접 토큰을 전달하는 것이 좋습니다. 메모리에 토큰을 넣고 필요에 따라 메시지의 암호 해독을 수행합니다.


1

사용 password_hashpassword_verify

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

그리고 해독하려면 :

<?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.';
}
?>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.