두 개의 다른 문자열이 동일한 MD5 해시 코드를 생성 할 수 있습니까?


93

각 바이너리 자산에 대해 MD5 해시를 생성합니다. 특정 바이너리 자산이 이미 애플리케이션에 있는지 확인하는 데 사용됩니다. 그러나 두 개의 다른 이진 자산이 동일한 MD5 해시를 생성 할 수 있습니다. 두 개의 다른 문자열이 동일한 MD5 해시를 생성 할 수 있습니까?

답변:


93

수십억 개의 자산 세트의 경우 무작위 충돌 가능성은 무시할 정도로 작습니다 . 걱정할 필요가 없습니다. 고려 생일 역설 , 2 ^ 64 (또는 18,446,744,073,709,551,616) 자원의 집합을 소정의 확률 단일 세트 내의 MD5 충돌은 50 %이다. 이 규모에서는 스토리지 용량 측면에서 Google을 능가 할 것입니다.

그러나 MD5 해시 기능이 손상 되었기 때문에 ( 충돌 공격에 취약 함 ) 결정된 공격자는 CPU 성능에 대해 몇 초 만에 2 개의 충돌 자산생성 할 수 있습니다 . 따라서 MD5를 사용하려면 그러한 공격자가 애플리케이션의 보안을 손상시키지 않도록해야합니다!

또한 공격자가 데이터베이스 의 기존 자산대한 충돌을 위조 할 수 있는 경우의 결과를 고려하십시오 . MD5 (2011 년 현재)에 대한 알려진 공격 ( 사전 이미지 공격 ) 은 없지만 충돌 공격에 대한 현재 연구를 확장하면 가능할 수 있습니다.

이것이 문제로 판명되면 SHA-2 시리즈 해시 함수 (SHA-256, SHA-384 및 SHA-512)를 살펴 보는 것이 좋습니다. 단점은 약간 느리고 해시 출력이 더 길다는 것입니다.


4
'Days'는 내가 이해하는이 시점에서 엄청난 과장입니다.
Nick Johnson

1
사실, 내 게시물을 업데이트했습니다. 2004 년 무작위 충돌 공격은 실제로 매우 빠릅니다. 2007 MD5 접두사 충돌 공격은 며칠이 걸릴 수 있습니다 -하지만 공격자 일반적으로 훨씬 더 유용하다
intgr

2
몇 시간 만에 두 개의 다른 실행 파일간에 충돌을 생성하는 작업 예제는 Rubens의 답변을 참조하십시오. :)
Nick Johnson

38

MD5는 해시 함수입니다 . 따라서 두 개의 서로 다른 문자열이 충돌 MD5 코드를 생성 할 수 있습니다.

특히 MD5 코드는 길이가 고정되어 있으므로 가능한 MD5 코드 수가 제한됩니다. 그러나 문자열 (길이에 관계없이)의 수는 확실히 무제한이므로 논리적으로 충돌 이 있어야 합니다.


12

예, 가능합니다. 이것은 사실 생일 문제 입니다. 그러나 동일한 MD5 해시를 갖는 두 개의 무작위로 선택된 문자열의 확률은 매우 낮습니다.

예제는 thisthis question을 참조하십시오 .


1
무슨 확률? 충돌? 아니요, 1, 즉 매우 높습니다. ;-)
Konrad Rudolph

글쎄요. 동일한 MD5 해시를 가진 두 개의 문자열이 확실히 존재합니다.
sharptooth

3
나는 이것을 비둘기 구멍 문제로 알고 있습니다.
Daniel A. White

생일 문제는 충돌 가능성과 관련이 있습니다. 증거 하나는 비들기 구멍 원리를 원하는가 있어야합니다
JK합니다.

내가 할 수 있다면 나는 당신의 대답을 두 번 투표 할 것입니다. 확률이 얼마나 "낮음"이라고 말하는가?
Alex Spencer

10

예, 물론입니다. MD5 해시는 유한 길이이지만 MD5 해시가 될 수있는 가능한 문자열은 무한합니다.


9

예, 두 개의 다른 문자열이 동일한 MD5 해시 코드를 생성 할 수 있습니다.

다음은 16 진 문자열에서 매우 유사한 바이너리 메시지를 사용하는 간단한 테스트입니다.

$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c6b384c4968b28812b676b49d40c09f8af4ed4cc  -
008ee33a9d58b51cfeb425b0959121c9

$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c728d8d93091e9c7b87b43d9e33829379231d7ca  -
008ee33a9d58b51cfeb425b0959121c9

그들은 다른 SHA-1 합계를 생성하지만 동일한 MD5 해시 값을 생성합니다. 둘째, 현이 매우 유사하기 때문에 그 차이를 찾기가 어렵습니다.

차이점은 다음 명령으로 찾을 수 있습니다.

$ diff -u <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2 | fold -w2) <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2 | fold -w2)
--- /dev/fd/63  2016-02-05 12:55:04.000000000 +0000
+++ /dev/fd/62  2016-02-05 12:55:04.000000000 +0000
@@ -33,7 +33,7 @@
 af
 bf
 a2
-00
+02
 a8
 28
 4b
@@ -53,7 +53,7 @@
 6d
 a0
 d1
-55
+d5
 5d
 83
 60

위의 충돌 예는 Marc Stevens에서 가져온 것 입니다. MD5의 단일 블록 충돌 , 2012; 그는 자신의 방법을 소스 코드와 함께 설명합니다 ( 논문에 대한 대체 링크 ).


또 다른 테스트 :

$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
756f3044edf52611a51a8fa7ec8f95e273f21f82  -
cee9a457e790cf20d4bdaa6d69f01e41

$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
6d5294e385f50c12745a4d901285ddbffd3842cb  -
cee9a457e790cf20d4bdaa6d69f01e41

다른 SHA-1 합계, 동일한 MD5 해시.

차이점은 1 바이트입니다.

$ diff -u <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2) <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2)
--- /dev/fd/63  2016-02-05 12:56:43.000000000 +0000
+++ /dev/fd/62  2016-02-05 12:56:43.000000000 +0000
@@ -19,7 +19,7 @@
 03
 65
 9e
-70
+74
 4f
 85
 34
@@ -41,7 +41,7 @@
 a3
 f4
 15
-5c
+dc
 bb
 86
 07

위의 예는 Tao Xie 및 Dengguo Feng : 단일 메시지 블록을 사용하여 MD5 충돌 구성 , 2010 에서 채택되었습니다 .


관련 :


4

예, 가능합니다. 이것을 해시 충돌 이라고합니다 .

하지만 MD5와 같은 알고리즘은 충돌 가능성을 최소화하도록 설계되었습니다.

MD5 의 Wikipedia 항목은 MD5의 몇 가지 취약점을 설명합니다.


4

더 많은 정보를 제공합니다. 수학적인 관점에서 해시 함수는 주입 적이 지 않습니다 .
이는 시작 세트와 결과 세트 사이에 일대일 (단방향) 관계가 없음을 의미합니다.

Wikipedia의 Bijection

편집 : 완전한 인젝 티브 해시 함수가 존재하려면 Perfect hashing 이라고 합니다.


1
출력 크기가 입력 크기보다 작 으면 완벽한 해싱 기능이 없습니다.
Paŭlo Ebermann

3

네, 그렇습니다! 충돌 발생할 가능성 있습니다 (위험은 매우 적지 만). 그렇지 않다면 꽤 효과적인 압축 방법이있을 것입니다!

EDIT :로서는 콘라드 루돌프 말한다 입력하는 잠재적으로 무한한 세트는 출력 (32 개 진수 문자)의 유한 집합으로 변환 충돌 무한 수의 결과.


3

다른 사람들이 말했듯이, 예, 두 개의 다른 입력간에 충돌이있을 수 있습니다. 그러나 귀하의 사용 사례에서는 이것이 문제라고 생각하지 않습니다. 나는 당신이 충돌을 겪을 것이라는 것을 매우 의심합니다. 저는 이전 작업에서 여러 이미지 (JPG, 비트 맵, PNG, 원시) 형식의 수십만 개의 이미지 파일을 지문 처리하는 데 MD5를 사용했으며 충돌이 없었습니다. .

그러나 어떤 종류의 데이터를 핑거 프린팅하려는 경우 두 개의 해시 알고리즘을 사용할 수 있습니다. 하나의 입력이 두 가지 다른 알고리즘의 동일한 출력을 생성 할 확률은 거의 불가능합니다.


1
실제로 공격자가 하나의 해시 알고리즘과 충돌을 생성 할 수있는 경우이를 사용하여 두 번째 알고리즘에 대한 충돌도 얻을 수 있습니다. 이것은 최근 crypto.stackexchange 에서 내 질문에 대해 논의되었습니다 .
Paŭlo Ebermann

2

나는 이것이 오래되었다는 것을 알고 있지만 내 해결책에 기여할 것이라고 생각했습니다. 2 ^ 128 개의 가능한 해시 조합이 있습니다. 따라서 생일 역설의 2 ^ 64 확률입니다. 아래의 솔루션이 충돌 가능성을 제거하지는 않지만 위험을 상당히 크게 줄일 수 있습니다.

2^64 = 18,446,744,073,709,500,000 possible combinations

내가 한 일은 입력 문자열을 기반으로 몇 개의 해시를 모아 해시로 간주하는 훨씬 더 긴 결과 문자열을 얻는 것입니다.

그래서 이것에 대한 의사 코드는 다음과 같습니다.

Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string))

그것은 충돌의 실질적인 비 개연성입니다. 그러나 당신이 슈퍼 편집증이되고 싶지만 그런 일이 일어나지 않고 저장 공간이 문제가되지 않는다면 (아니면 컴퓨팅 주기도 아닙니다) ...

Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string)) 
         & Hash(Reverse(SpellOutLengthWithWords(Length(string)))) 
         & Hash(Rotate13(string)) Hash(Hash(string)) & Hash(Reverse(Hash(string)))

좋아요, 가장 깨끗한 해결책은 아니지만, 이제 얼마나 자주 충돌이 발생하는지에 대해 더 많은 플레이를 할 수 있습니다. 요점까지 나는 용어의 모든 현실적인 의미에서 불가능하다고 가정 할 수 있습니다.

제 생각에는 충돌의 가능성이 "확실하지 않은"것으로 간주 할만큼 충분히 드물다고 생각하지만 필요에 따라 발생할 가능성은 거의 없습니다.

이제 가능한 조합이 크게 늘어납니다. 얼마나 많은 조합이 당신을 얻을 수 있는지에 대해 오랜 시간을 할애 할 수는 있지만 이론적으로는 위에 인용 된 숫자보다 훨씬 더 많은 것을 얻을 수 있다고 말할 것입니다.

2^64 (or 18,446,744,073,709,551,616) 

아마도 100 자리 정도 더 될 것입니다. 이것이 줄 수있는 이론적 최대 값은

가능한 결과 문자열 수 :

528294531135665246352339784916516606518847326036121522127960709026673902556724859474417255887657187894674394993257128678882347559502685537250538978462939576908386683999005084168731517676426441053024232908211188404148028292751561738838396898767036486479538580897737998336 인스 타 그램 1


1

해시 충돌이 예상만큼 드물지 않기 때문에 우리의 요구 사항에 따라 해싱 알고리즘을 신중하게 선택해야한다고 생각합니다. 최근에 내 프로젝트에서 매우 간단한 해시 충돌 사례를 발견했습니다. 해싱을 위해 xxhash의 Python 래퍼를 사용하고 있습니다. 링크 : https://github.com/ewencp/pyhashxx

s1 = 'mdsAnalysisResult105588'
s2 = 'mdsAlertCompleteResult360224'
pyhashxx.hashxx(s1) # Out: 2535747266
pyhashxx.hashxx(s2) # Out: 2535747266

그것은 시스템에서 매우 까다로운 캐싱 문제를 일으켰고 마침내 해시 충돌이라는 것을 발견했습니다.

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