해시와 암호화 알고리즘 사이에 많은 혼란이 있으며 다음에 대한 전문가의 조언을 듣고 싶습니다.
-
해시와 암호화를 사용하는 경우
-
해시 또는 암호화 알고리즘을 이론적 / 수학적 수준과 다르게 만드는 것, 즉 해시를 비가 역적으로 만들 수있는 것 (무지개 나무의 도움없이)
여기에 몇 가지 유사한 내가 찾던으로 많은 세부 사항으로에 가지 않았다 SO 질문 :
답변
글쎄, 당신은 Wikipedia 에서 그것을 찾을 수 있습니다 …하지만 설명을 원하기 때문에 여기서 최선을 다하겠습니다.
해시 함수
임의의 길이 입력과 (보통) 고정 길이 (또는 더 작은 길이) 출력 간의 매핑을 제공합니다. 간단한 crc32부터 MD5 또는 SHA1 / 2 / 256 / 512와 같은 완전히 암호화 된 해시 함수에 이르기까지 다양합니다. 요점은 단방향 매핑이 진행되고 있다는 것입니다. 모든 함수는 입력 할 수있는 것보다 작은 출력을 생성하기 때문에 항상 1 : 1의 매핑 (충돌이 항상 있음을 의미 함)입니다 (가능한 모든 1mb 파일을 MD5에 공급하는 경우 많은 충돌이 발생합니다).
그들이 뒤집기 어려운 (또는 실용 상 불가능한) 이유는 그들이 내부적으로 일하는 방식 때문입니다. 대부분의 암호화 해시 함수는 입력 세트를 여러 번 반복하여 출력을 생성합니다. 따라서 고정 길이의 입력 청크 (알고리즘에 따라 다름)를 보면 해시 함수는 현재 상태를 호출합니다. 그런 다음 상태를 반복하고 새로운 상태로 변경하여 피드백을 자체로 사용합니다 (MD5는 512 비트 데이터 청크마다 64 회이 작업을 수행함). 그런 다음 어떻게 든이 모든 반복의 결과 상태를 다시 결합하여 결과 해시를 형성합니다.
이제 해시를 해독하려면 먼저 주어진 해시를 반복 된 상태로 분할하는 방법을 알아야합니다 (1 개의 데이터 청크 크기보다 작은 입력의 가능성, 더 큰 입력의 경우 많은 가능성). 그런 다음 각 상태의 반복을 되돌려 야합니다. 자,이 매우 어려운 이유를 추론하려고 상상 설명하기 a
및 b
다음 식 : 10 = a + b
. 10 가지 긍정적 인 조합이 a
있으며 효과 b
가 있습니다. 이제 여러 번 반복하십시오.tmp = a + b; a = b; b = tmp
. 64 번의 반복에서는 10 ^ 64 개 이상의 시도가 가능합니다. 그리고 그것은 반복에서 반복까지 일부 상태가 보존되는 단순한 추가입니다. 실제 해시 함수는 둘 이상의 작업을 수행합니다 (MD5는 4 개의 상태 변수에 대해 약 15 개의 작업을 수행함). 그리고 다음 반복은 이전의 상태에 의존하고 이전은 현재 상태를 만들 때 파괴되므로 주어진 출력 상태로 이어지는 입력 상태를 결정하는 것은 불가능합니다 (각 반복마다). 이를 수많은 가능성과 결합하면 MD5조차도 거의 무한한 (그러나 무한하지 않은) 양의 리소스를 사용하게됩니다. 너무 많은 리소스
암호화 기능
임의 길이의 입력과 출력간에 1 : 1 매핑을 제공합니다. 그리고 그들은 항상 가역적입니다. 주목해야 할 것은 몇 가지 방법을 사용하여 가역적이라는 것입니다. 그리고 주어진 키에 대해 항상 1 : 1입니다. 이제 동일한 출력을 생성 할 수있는 여러 input : key 쌍이 있습니다 (사실 일반적으로 암호화 기능에 따라 다름). 좋은 암호화 데이터는 랜덤 노이즈와 구별 할 수 없습니다. 이것은 항상 일관된 형식의 좋은 해시 출력과 다릅니다.
사용 사례
값을 비교하려고하지만 일반 표현을 저장할 수없는 경우 (여러 가지 이유로) 해시 함수를 사용하십시오. 보안상의 이유로 비밀번호를 일반 텍스트로 저장하고 싶지 않기 때문에 비밀번호는이 사용 사례에 매우 적합해야합니다. 그러나 파일 시스템에서 불법 복제 된 음악 파일을 확인하려면 어떻게해야합니까? 음악 파일 당 3MB를 저장하는 것은 비현실적입니다. 대신 파일의 해시를 가져 와서 저장하십시오 (md5는 3mb 대신 16 바이트를 저장합니다). 그렇게하면 각 파일을 해시하고 저장된 해시 데이터베이스와 비교할 수 있습니다 (재 인코딩, 파일 헤더 변경 등으로 인해 실제로는 잘 작동하지 않지만 사용 사례의 예입니다).
입력 데이터의 유효성을 확인할 때 해시 함수를 사용하십시오. 그것이 그들이 디자인 한 것입니다. 두 개의 입력이 있고 동일한 지 확인하려면 해시 함수를 통해 두 가지를 모두 실행하십시오. 작은 입력 크기의 경우 충돌 가능성이 천문학적으로 낮습니다 (좋은 해시 함수 가정). 이것이 암호를 권장하는 이유입니다. 최대 32 자의 암호의 경우 md5는 출력 공간의 4 배입니다. SHA1의 출력 공간은 약 6 배입니다. SHA512의 출력 공간은 약 16 배입니다. 당신은 실제로 암호 가 무엇인지 상관하지 않고 저장된 암호 와 동일한 지 걱정합니다. 따라서 비밀번호에 해시를 사용해야합니다.
입력 데이터를 다시 가져와야 할 때마다 암호화를 사용하십시오. 단어 가 필요하다는 것을 주목하십시오 . 신용 카드 번호를 저장하는 경우 특정 시점에 다시 가져와야하지만 일반 텍스트는 저장하지 않습니다. 대신 암호화 된 버전을 저장하고 키를 최대한 안전하게 유지하십시오.
해시 함수는 데이터 서명에도 유용합니다. 예를 들어, HMAC를 사용하는 경우 알려진 값이지만 전송되지 않은 값 (비밀 값)으로 연결된 데이터 해시를 가져 와서 데이터에 서명합니다. 따라서 일반 텍스트와 HMAC 해시를 보냅니다. 그런 다음 수신자는 제출 된 데이터를 알려진 값으로 해시하고 전송 된 HMAC와 일치하는지 확인합니다. 동일하다면, 비밀 가치가없는 당사자에 의해 변조되지 않은 것입니다. 이것은 일반적으로 HTTP 프레임 워크에 의한 보안 쿠키 시스템과 데이터 무결성을 보장하고자하는 HTTP를 통한 데이터의 메시지 전송에 사용됩니다.
비밀번호 해시에 대한 참고 사항 :
암호화 해시 함수의 주요 특징은 작성하기가 매우 빠르며 역전이 매우 어렵거나 느리다는 점입니다 (실제로는 불가능합니다). 암호에 문제가 있습니다. 보관 sha512(password)
하면 무지개 테이블이나 무차별 대입 공격을 막기위한 조치를 취하지 않은 것입니다. 해시 기능은 속도를 위해 설계되었습니다. 따라서 공격자가 해시 함수를 통해 사전을 실행하고 각 결과를 테스트하는 것은 쉽지 않습니다.
솔트를 추가하면 해시에 약간의 알 수없는 데이터가 추가되므로 문제가 해결됩니다. 따라서 일치하는 것을 찾는 대신 md5(foo)
알려진 소금에 첨가 할 때 md5(foo.salt)
(매우 어려운) 무언가를 찾아야합니다 . 그러나 소금을 알고 있으면 사전을 실행하는 것만으로 속도 문제를 해결하지 못합니다.
그래서, 이것을 다루는 방법이 있습니다. 널리 사용되는 방법 중 하나는 키 강화 (또는 키 늘이기)입니다. 기본적으로 해시를 여러 번 반복합니다 (일반적으로 수천). 이것은 두 가지 일을합니다. 먼저 해싱 알고리즘의 런타임이 상당히 느려집니다. 둘째, 올바르게 구현되면 (각 반복에서 입력과 소금을 다시 전달) 실제로 출력의 엔트로피 (사용 가능한 공간)를 증가시켜 충돌 가능성을 줄입니다. 간단한 구현은 다음과 같습니다.
var hash = password + salt;
for (var i = 0; i < 5000; i++) {
hash = sha512(hash + password + salt);
}
PBKDF2 , BCrypt 와 같은 다른 표준 구현이 있습니다. 그러나이 기술은 상당수의 보안 관련 시스템 (예 : PGP, WPA, Apache 및 OpenSSL)에서 사용됩니다.
결론 hash(password)
은 충분하지 않습니다. hash(password + salt)
더 낫지 만 여전히 충분하지 않습니다 … 확장 해시 메커니즘을 사용하여 비밀번호 해시를 생성하십시오 …
사소한 스트레칭에 대한 또 다른 참고 사항
어떤 상황에서도 하나의 해시 출력을 해시 함수로 직접 다시 공급하지 마십시오 .
hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
hash = sha512(hash); // <-- Do NOT do this!
}
그 이유는 충돌과 관련이 있습니다. 가능한 출력 공간 (가능한 출력 수)이 입력 공간보다 작기 때문에 모든 해시 함수에 충돌이 있음을 기억하십시오. 왜 그런지 알아 보려면 어떻게되는지 봅시다. 이를 시작하기 위해 0.001 %의 충돌 가능성이 있다고 가정합니다 sha1()
(실제로는 훨씬 낮지 만 데모 목적으로).
hash1 = sha1(password + salt);
이제 hash1
충돌 확률은 0.001 %입니다. 우리는 다음을 수행 할 때 hash2 = sha1(hash1);
, 모든 충돌은 hash1
자동으로의 충돌된다hash2
. 이제 우리는 해시 1의 속도가 0.001 %이며, 두 번째 sha1()
호출이이를 더합니다. 이제 hash2
충돌 확률은 0.002 %입니다. 두 배나 많은 기회입니다! 각 반복은 0.001%
결과에 또 다른 충돌 가능성을 추가 합니다. 따라서 1000 회 반복으로 충돌 가능성이 사소한 0.001 %에서 1 %로 증가했습니다. 이제 열화는 선형 적이며 실제 확률은 훨씬 작지만 효과는 같습니다 (단일 충돌 가능성 md5
은 약 1 / (2 128 ) 또는 1 / (3×10 38입니다).). 작은 것처럼 보이지만 생일 공격 덕분에 실제로는 작지는 않습니다.
대신 매번 소금과 암호를 다시 추가하면 데이터를 다시 해시 함수에 다시 도입하게됩니다. 따라서 특정 라운드의 충돌은 더 이상 다음 라운드의 충돌이 아닙니다. 그래서:
hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
hash = sha512(hash + password + salt);
}
기본 sha512
기능 과 충돌 가능성이 동일 합니다. 당신이 원하는 것입니다. 대신 사용하십시오.
답변
해시 함수는 빵 한 덩어리를 굽는 것과 같은 것으로 간주 될 수 있습니다. 입력 (밀가루, 물, 효모 등)으로 시작하고 해시 기능 (믹싱 + 베이킹)을 적용한 후에는 빵 한 덩어리가 출력됩니다.
다른 방법으로가는 것은 매우 어렵습니다-빵을 밀가루, 물, 효모로 다시 분리 할 수는 없습니다-베이킹 과정에서 손실 된 것 중 일부는 물이나 밀가루 또는 효모가 얼마나 많이 사용되었는지 정확하게 알 수 없습니다 정보는 해싱 기능 (일명 오븐)에 의해 파괴 되었기 때문에 특정 덩어리.
입력의 많은 다른 변형은 이론적으로 동일한 덩어리를 생성 할 것입니다 (예 : 2 컵의 물과 1 tsbp의 효모는 2.1 컵의 물과 0.9tsbp의 효모와 정확히 동일한 덩어리를 생성합니다). 정확히 어떤 입력의 콤보가 그것을 생산했는지.
반면에 암호화는 안전 금고로 볼 수 있습니다. 당신이 거기에 넣은 것은 처음에 잠겨 있던 열쇠를 가지고 있다면 다시 나옵니다. 대칭 작업입니다. 키와 일부 입력이 주어지면 특정 출력이 나타납니다. 해당 출력과 동일한 키가 주어지면 원래 입력을 다시 얻습니다. 1 : 1 매핑입니다.
답변
원래 입력을 되돌릴 수 없게하려면 해시를 사용하고, 할 때는 암호화를 사용하십시오.
해시는 일부 입력을 가져 와서 약간의 비트로 변환합니다 (일반적으로 32 비트 정수, 64 비트 정수 등의 숫자로 간주). 동일한 입력은 항상 동일한 해시를 생성하지만 원칙적으로 프로세스에서 정보를 잃어 버리므로 원래 입력을 안정적으로 재현 할 수 없습니다 (그러나 몇 가지주의 사항이 있습니다).
암호화는 원칙적으로 암호화 기능에 입력 한 모든 정보를 유지하므로 특정 키를 소유하지 않고도 누구나 원래 입력으로 되돌릴 수 없도록하는 것이 이상적입니다.
해싱의 간단한 예
다음은 해싱이 왜 일반적인 입력을 되돌릴 수 없는지 이해하는 데 도움이되는 간단한 예입니다. 1 비트 해시를 만들고 있다고 가정 해 보겠습니다. 내 해시 함수는 비트 문자열을 입력으로 사용하고 입력 문자열에 짝수의 비트가 설정되어 있으면 해시를 1로 설정하고 홀수가 있으면 0을 설정합니다.
예:
Input Hash
0010 0
0011 1
0110 1
1000 0
해시가 0 인 결과 값이 많고 해시가 1 인 결과 값이 많이 있습니다. 해시가 0임을 알고 있으면 원래 입력이 무엇인지 확실하게 알 수 없습니다.
그건 그렇고,이 1 비트 해시는 정확하게 고안되지 않았습니다 … 패리티 비트를 살펴보십시오 .
간단한 암호화 예
간단한 문자 대체를 사용하여 텍스트를 암호화 할 수 있습니다 (예 : 입력이 A 인 경우 B를 쓴다). 입력이 B 인 경우 C를 쓴다. 알파벳의 끝까지 (입력이 Z 인 경우) A를 다시 쓰십시오.
Input Encrypted
CAT DBU
ZOO APP
간단한 해시 예제와 마찬가지로이 유형의 암호화는 역사적으로 사용되었습니다 .
답변
해싱 및 암호화 / 암호 해독 기술에 대한 기본 개요는 다음과 같습니다.
해싱 :
당신이 경우 해시 있는 일반 텍스트를 다시는 해시 텍스트와 같은 일반 텍스트를 얻을 수 없다 . 간단히 말해 단방향 프로세스입니다.
암호화 및 복호화 :
키 를 사용 하여 일반 텍스트 를 다시 암호화하면 same (symetric) / diffrent (asymentric) 키를 사용하여 암호화 된 텍스트를 해독 하여 동일한 일반 텍스트 를 얻을 수 있습니다 .
업데이트 :
편집 된 질문에 언급 된 사항을 해결합니다.
1. 해시 및 암호화 사용시기
해싱 은 누군가에게 파일을 보내려는 경우에 유용합니다. 그러나 다른 사람이 파일을 가로 채서 변경할 수도 있습니다. 따라서 수신자가 해시 값을 공개적으로 게시하는 경우 수신자가 올바른 파일인지 확인할 수있는 방법입니다. 이렇게하면 수신자가 수신 한 파일의 해시 값을 계산하여 해시 값과 일치하는지 확인할 수 있습니다.
누군가에게 보낼 메시지가 있으면 암호화 가 좋습니다. 키를 사용하여 메시지를 암호화하면 수신자는 동일한 (또는 다른) 키로 암호를 해독하여 원래 메시지를 되돌립니다.
크레딧
2. 해시 또는 암호화 알고리즘을 이론적 / 수학적 수준과 다르게 만드는 것, 즉 해시를 돌이킬 수 없게 만드는 것 (무지개 나무의 도움없이)
기본적으로 해싱은 정보는 손실되지만 암호화는하지 않는 작업입니다 . 이해하기 쉽도록 간단한 수학적 방법의 차이점을 살펴 봅시다. 물론 반복과 관련된 수학적 연산이 훨씬 복잡합니다.
암호화 / 암호 해독 (가역) :
추가 :
4 + 3 = 7
합계를 취하고 추가 중 하나를 빼서 되돌릴 수 있습니다
7 - 3 = 4
곱셈 :
4 * 5 = 20
제품을 가져 와서 요인 중 하나로 나누어서 되돌릴 수 있습니다
20 / 4 = 5
따라서 여기서 우리는 추가 / 요인 중 하나가 decrpytion key이고 result (7,20)가 암호화 된 텍스트라고 가정 할 수 있습니다.
해싱 (가역 불가능) :
모듈로 구분 :
22 % 7 = 1
몫과 피제수에 제수를 재구성하기 위해 (또는 그 반대로) 수행 할 수있는 작업이 없기 때문에 이는 되돌릴 수 없습니다.
‘?’위치를 채우는 작업을 찾을 수 있습니까? 입니까?
1 ? 7 = 22 1 ? 22 = 7
따라서 해시 함수는 모듈로 나누기와 동일한 수학적 품질을 가지며 정보를 잃어 버립니다.
답변
내 한 라이너 … 일반적으로 면접관은 아래 답변을 원했습니다.
해싱은 한 가지 방법입니다. 해시 코드에서 데이터 / 문자열을 변환 할 수 없습니다.
암호화는 양방향입니다. 키가 있으면 암호화 된 문자열을 다시 해독 할 수 있습니다.
답변
해시 함수 고정 크기의 텍스트에 텍스트의 가변 크기의 양 변.
출처 : https://en.wikipedia.org/wiki/Hash_function
PHP의 해시 함수
해시는 문자열을 해시 문자열로 바꿉니다. 아래를 참조하십시오.
해시시:
$str = 'My age is 29';
$hash = hash('sha1', $str);
echo $hash; // OUTPUT: 4d675d9fbefc74a38c89e005f9d776c75d92623e
암호는 일반적으로 읽을 수있는 텍스트 대신 해시 표시로 저장됩니다. 최종 사용자가 비밀번호로 보호 된 애플리케이션에 액세스하려면 인증 중에 비밀번호를 제공해야합니다. 사용자가 자신의 비밀번호를 제출하면 유효한 인증 시스템이 비밀번호를 수신하고이 지정된 비밀번호를 해시합니다. 이 비밀번호 해시는 시스템에서 알려진 해시와 비교됩니다. 평등 한 경우 액세스 권한이 부여됩니다.
해체 :
SHA1은 단방향 해시입니다. 이는 해시를 해시 할 수 없음을 의미합니다.
그러나 해시를 무차별 대입 할 수 있습니다. https://hashkiller.co.uk/sha1-decrypter.aspx를 참조 하십시오 .
MD5는 또 다른 해시입니다. MD5 디해 셔는이 웹 사이트 ( https://www.md5online.org/) 에서 찾을 수 있습니다 .
해시에 대한 무차별 대입 공격을 막기 위해 소금을 줄 수 있습니다. PHP에서는 password_hash()
암호 해시를 만드는 데 사용할 수 있습니다 . 이 기능은 password_hash()
자동으로 소금을 만듭니다. 비밀번호 해시 (소금 포함)에서 비밀번호를 확인하려면을 사용하십시오 password_verify()
.
// Invoke this little script 3 times, and it will give you everytime a new hash
$password = '1234';
$hash = password_hash($password, PASSWORD_DEFAULT);
echo $hash;
// OUTPUT
$2y$10$ADxKiJW/Jn2DZNwpigWZ1ePwQ4il7V0ZB4iPeKj11n.iaDtLrC8bu
$2y$10$H8jRnHDOMsHFMEZdT4Mk4uI4DCW7/YRKjfdcmV3MiA/WdzEvou71u
$2y$10$qhyfIT25jpR63vCGvRbEoewACQZXQJ5glttlb01DmR4ota4L25jaW
하나의 비밀번호는 하나 이상의 해시로 표시 될 수 있습니다. 를 사용하여 다른 비밀번호 해시로 비밀번호를 확인하면 비밀번호가 password_verify()
유효한 비밀번호로 승인됩니다.
$password = '1234';
$hash = '$2y$10$ADxKiJW/Jn2DZNwpigWZ1ePwQ4il7V0ZB4iPeKj11n.iaDtLrC8bu';
var_dump( password_verify($password, $hash) );
$hash = '$2y$10$H8jRnHDOMsHFMEZdT4Mk4uI4DCW7/YRKjfdcmV3MiA/WdzEvou71u';
var_dump( password_verify($password, $hash) );
$hash = '$2y$10$qhyfIT25jpR63vCGvRbEoewACQZXQJ5glttlb01DmR4ota4L25jaW';
var_dump( password_verify($password, $hash) );
// OUTPUT
boolean true
boolean true
boolean true
암호화 기능은 반대로 암호화 키 및 부사를 사용하여 암호문 무의미한 텍스트로 변환한다.
출처 : https://en.wikipedia.org/wiki/Encryption
PHP의 암호화
암호화를 처리하는 일부 PHP 코드를 살펴 보겠습니다.
— Mcrypt 확장 —
암호화 :
$cipher = MCRYPT_RIJNDAEL_128;
$key = 'A_KEY';
$data = 'My age is 29';
$mode = MCRYPT_MODE_ECB;
$encryptedData = mcrypt_encrypt($cipher, $key , $data , $mode);
var_dump($encryptedData);
//OUTPUT:
string '„Ùòyªq³¿ì¼üÀpå' (length=16)
해독 :
$decryptedData = mcrypt_decrypt($cipher, $key , $encryptedData, $mode);
$decryptedData = rtrim($decryptedData, "\0\4"); // Remove the nulls and EOTs at the END
var_dump($decryptedData);
//OUTPUT:
string 'My age is 29' (length=12)
— OpenSSL 확장 —
Mcrypt 확장은 7.1에서 더 이상 사용되지 않습니다. PHP 7.2에서 제거되었습니다. OpenSSL 확장은 PHP 7에서 사용해야합니다. 아래 코드 스 니펫을 참조하십시오.
$key = 'A_KEY';
$data = 'My age is 29';
// ENCRYPT
$encryptedData = openssl_encrypt($data , 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($encryptedData);
// DECRYPT
$decryptedData = openssl_decrypt($encryptedData, 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($decryptedData);
//OUTPUT
string '4RJ8+18YkEd7Xk+tAMLz5Q==' (length=24)
string 'My age is 29' (length=12)
답변
대칭 암호화 :
대칭 암호화는 공유 키 또는 공유 비밀 암호화라고도합니다. 대칭 암호화에서는 단일 키를 사용하여 트래픽을 암호화하고 해독합니다.
비대칭 암호화 :
비대칭 암호화는 공개 키 암호화라고도합니다. 비대칭 암호화는 암호화와 암호 해독에 사용되는 두 가지 키가 사용된다는 점에서 대칭 암호화와 다릅니다. 가장 일반적인 비대칭 암호화 알고리즘은 RSA
입니다.
대칭 암호화와 비교할 때 비대칭 암호화는 계산 부담이 높고 속도가 훨씬 느립니다. 따라서 일반적으로 페이로드 데이터를 보호하는 데 사용되지 않습니다. 대신, 주요 장점은 비보안 매체 (예 : 인터넷)를 통해 보안 채널을 설정하는 기능입니다. 이는 데이터를 암호화하는 데만 사용할 수있는 공개 키 교환으로 이루어집니다. 절대 공유되지 않는 보완 개인 키는 암호 해독에 사용됩니다.
해싱 :
마지막으로, 해싱은 암호화와 다른 암호화 보안의 한 형태입니다. 암호화는 메시지를 먼저 암호화 한 다음 해독하는 데 사용되는 2 단계 프로세스 인 반면 해싱은 메시지를 돌이킬 수없는 고정 길이 값 또는 해시로 압축합니다. 네트워킹에서 볼 수있는 가장 일반적인 해싱 알고리즘 중 두 가지는 MD5
및 SHA-1
입니다.
자세한 내용은 여기를 참조하십시오 : http://packetlife.net/blog/2010/nov/23/symmetric-asymmetric-encryption-hashing/