각 바이너리 자산에 대해 MD5 해시를 생성합니다. 특정 바이너리 자산이 이미 애플리케이션에 있는지 확인하는 데 사용됩니다. 그러나 두 개의 다른 이진 자산이 동일한 MD5 해시를 생성 할 수 있습니다. 두 개의 다른 문자열이 동일한 MD5 해시를 생성 할 수 있습니까?
각 바이너리 자산에 대해 MD5 해시를 생성합니다. 특정 바이너리 자산이 이미 애플리케이션에 있는지 확인하는 데 사용됩니다. 그러나 두 개의 다른 이진 자산이 동일한 MD5 해시를 생성 할 수 있습니다. 두 개의 다른 문자열이 동일한 MD5 해시를 생성 할 수 있습니까?
답변:
수십억 개의 자산 세트의 경우 무작위 충돌 가능성은 무시할 정도로 작습니다 . 걱정할 필요가 없습니다. 고려 생일 역설 , 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)를 살펴 보는 것이 좋습니다. 단점은 약간 느리고 해시 출력이 더 길다는 것입니다.
예, 두 개의 다른 문자열이 동일한 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 에서 채택되었습니다 .
관련 :
더 많은 정보를 제공합니다. 수학적인 관점에서 해시 함수는 주입 적이 지 않습니다 .
이는 시작 세트와 결과 세트 사이에 일대일 (단방향) 관계가 없음을 의미합니다.
편집 : 완전한 인젝 티브 해시 함수가 존재하려면 Perfect hashing 이라고 합니다.
다른 사람들이 말했듯이, 예, 두 개의 다른 입력간에 충돌이있을 수 있습니다. 그러나 귀하의 사용 사례에서는 이것이 문제라고 생각하지 않습니다. 나는 당신이 충돌을 겪을 것이라는 것을 매우 의심합니다. 저는 이전 작업에서 여러 이미지 (JPG, 비트 맵, PNG, 원시) 형식의 수십만 개의 이미지 파일을 지문 처리하는 데 MD5를 사용했으며 충돌이 없었습니다. .
그러나 어떤 종류의 데이터를 핑거 프린팅하려는 경우 두 개의 해시 알고리즘을 사용할 수 있습니다. 하나의 입력이 두 가지 다른 알고리즘의 동일한 출력을 생성 할 확률은 거의 불가능합니다.
나는 이것이 오래되었다는 것을 알고 있지만 내 해결책에 기여할 것이라고 생각했습니다. 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
해시 충돌이 예상만큼 드물지 않기 때문에 우리의 요구 사항에 따라 해싱 알고리즘을 신중하게 선택해야한다고 생각합니다. 최근에 내 프로젝트에서 매우 간단한 해시 충돌 사례를 발견했습니다. 해싱을 위해 xxhash의 Python 래퍼를 사용하고 있습니다. 링크 : https://github.com/ewencp/pyhashxx
s1 = 'mdsAnalysisResult105588'
s2 = 'mdsAlertCompleteResult360224'
pyhashxx.hashxx(s1) # Out: 2535747266
pyhashxx.hashxx(s2) # Out: 2535747266
그것은 시스템에서 매우 까다로운 캐싱 문제를 일으켰고 마침내 해시 충돌이라는 것을 발견했습니다.