PHP를 사용하여 암호를 암호화하고 해독하는 가장 좋은 방법은? [복제하다
-
18-09-2019 - |
문제
가능한 복제 :
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"
);
경고: 위의 예제는 정보를 암호화하지만 암호화를 방지하기 위해 암호 텍스트를 인증하지는 않습니다. 당신은해야합니다 ~ 아니다 보안을위한 무단 암호화에 의존하십시오, 특히 제공된 코드는 오라클 공격을 패딩하는 데 취약하기 때문에.
또한보십시오:
- https://stackoverflow.com/a/30189841/2224584
- https://stackoverflow.com/a/30166085/2224584
- https://stackoverflow.com/a/30159120/2224584
또한 암호화 키에 "비밀번호"만 사용하지 마십시오. 암호화 키는 임의의 문자열입니다.
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
).
대본
user-pass
데이터베이스에 MD5에 저장되며 각 사용자가 시스템에 로그인하도록 유효성을 검사하는 데 사용됩니다. 이 사용자 통과입니다 다른 각 사용자에 대해.- 데이터베이스의 각 사용자 항목에는 MD5 A가 있습니다.
system-pass
데이터의 암호화/암호 해독. 이 시스템 패스는 같은 각 사용자에 대해. - 사용자가 시스템에서 제거 될 때마다 기존 시스템 통과에 따라 암호화 된 모든 데이터는 보안 문제를 피하기 위해 새로운 시스템 패스로 다시 암호화해야합니다.