"암호문 단독공격"의 두 판 사이의 차이
(→소스) |
잔글 |
||
(사용자 2명의 중간 판 49개는 보이지 않습니다) | |||
1번째 줄: | 1번째 줄: | ||
− | '''암호문 단독공격 '''(Ciphertext Only Attack; COA)이란 | + | '''암호문 단독공격'''<!--암호문단독공격, 암호문 단독 공격-->(Ciphertext Only Attack; COA)이란 도청자가 [[알고리즘]]을 알고 있고, [[암호문]]을 가로챌 수 있다는 가정하에 |
− | + | 도청자가 어떤 암호문을 얻어서 대응되는 평문과 키를 찾는 공격을 말한다. 도청자는 암호문을 가지고 통계적 성질, 문장의 특성 등을 추정하여 해독하기 때문에, 가장 쉽게 적용될 수 있는 공격이다. | |
− | 예를 들자면, 영어로 된 평문을 | + | 예를 들자면, 영어로 된 평문을 [[암호화]]시킨 암호문을 암호문 단독 공격으로 얻어냈을 때 영어에서 가장 많이 쓰이는 글자가 e이기 때문에 가장 많이 나오는 글자는 e일 것이라고 예측을 하는 것이다.<ref>laon, 〈[https://steemit.com/kr/@laon/6whr3f 암호분석의 분류]〉, 《스팀잇》</ref> |
== 개요 == | == 개요 == | ||
− | 공격자가 가장 적은 정보를 가지고 공격하는 것을 암호문 단독 공격이라 한다. 이 공격에서 공격자는 같은 암호키를 사용하여 같은 | + | 공격자가 가장 적은 정보를 가지고 공격하는 것을 암호문 단독 공격이라 한다. 이 공격에서 공격자는 같은 암호키를 사용하여 같은 [[알고리즘]]으로 [[암호화]]된 유한 암호문 집합만을 가지고 있다. 따라서 공격자의 목표는 대응되는 평문을 찾거나 사용된 암호키를 찾거나 암호 |
− | 키를 찾지 못하였지만 암호키 없이 암호문을 복호화할 수 있는 새로운 알고리즘을 발견하는 것이다. 기지 평문 공격에서 공격자는 암호문뿐만 아니라 대응되는 평문도 가지고 있다. 하지만 가지고 있는 암호문/평문 쌍을 공격자가 선택할 수 없다. 이 공격에서 공격자의 목표는 사용된 암호키를 찾거나 암호키를 찾지 못하였지만 암호키 없이 암호문을 복호화할 수 있는 새로운 알고리즘을 발견하는 것이다.<ref> index-of, 〈[http://index-of.co.uk/Cryptology/01.pdf 제 1 장 암호알고리즘 개요]〉, 《개인 웹 사이트》</ref> | + | 키를 찾지 못하였지만, 암호키 없이 암호문을 복호화할 수 있는 새로운 알고리즘을 발견하는 것이다. 기지 평문 공격에서 공격자는 암호문뿐만 아니라 대응되는 평문도 가지고 있다. 하지만 가지고 있는 암호문/평문 쌍을 공격자가 선택할 수 없다. 이 공격에서 공격자의 목표는 사용된 암호키를 찾거나 암호키를 찾지 못하였지만, 암호키 없이 암호문을 복호화할 수 있는 새로운 알고리즘을 발견하는 것이다.<ref> index-of, 〈[http://index-of.co.uk/Cryptology/01.pdf 제 1 장 암호알고리즘 개요]〉, 《개인 웹 사이트》</ref> |
== 구현 == | == 구현 == | ||
− | + | msg = <font color=blue>'53%%#305))6*;4826)4%=\')4%);806*;48#8@60\'))85;1%(;:-%*8#83(88)5*#;46(;88*96*?;8)*%(;485);5*#2:*%(;4956*2(5*c4)8@8*;4069285);)6#8)4%%;1(%9;48081;8:8%1;48#85;4\')-485#528806*81(%9;48;(88;4(%?34;48)4%;161;:188;%?;' | |
− | msg = '53%%#305))6*;4826)4%=\')4%);806*;48#8@60\'))85;1%(;:-%*8#83(88)5*#;46(;88*96*?;8)*%(; | + | <font color=green># 메세지 내에서 어떤 문자가 몇 개 나왔는지.... |
− | #메세지 내에서 어떤 문자가 몇 개 나왔는지.... | + | # 빈도수를 체크하는 프로그램 |
− | #빈도수를 체크하는 프로그램 | + | # 구조는 딕셔너리[키(문자)에 대한 값(개수)]으로 구성 |
− | #구조는 딕셔너리[키(문자)에 | + | # 암호문만 알고 있을때 사용 가능!!! |
− | #암호문만 알고 | + | # 빈도수 많은 걸로 맞춰가는 것 외에 방법이 없음 |
− | #빈도수 많은 걸로 | + | <font color=black>def check(msg): |
− | def check(msg): | + | fa = {} |
− | + | for c in msg: | |
− | + | if c in fa: | |
− | + | fa[c] += 1 | |
− | + | else: | |
− | + | fa[c] = 1 | |
− | + | return fa | |
− | |||
def dec(msg): | def dec(msg): | ||
− | + | pmsg = '' | |
− | + | for c in msg: | |
− | + | <font color=green># 통계적 기법을 이용하여 | |
− | + | # 제일 많이 나온 순서대로 영문자 출현빈도수와 비교해서 치환 | |
− | + | <font color=black>if c == '8': | |
− | + | c = 'e' | |
− | + | elif c == ';': | |
− | + | c = 't' | |
− | + | elif c =='4': | |
− | + | c = 'h' | |
− | + | elif c =='#': | |
− | + | c = 'a' | |
− | + | pmsg = pmsg + c | |
− | + | <font color=green># 치환한 문자로 문자열 생성 | |
− | + | <font color=black>return pmsg | |
− | |||
− | |||
def main(): | def main(): | ||
− | + | fa = check(msg) | |
− | + | cnt = 0 <font color=green># 한 줄에 3개씩 출력 | |
− | + | <font color=green># 딕셔너리의 키와 값을 출력 | |
+ | <font color=black>for k, v in fa.items(): | ||
+ | cnt += 1 | ||
+ | if cnt % 3 == 0: | ||
+ | <font color=red>print<font color=black>("<font color=blue>'{}' = {} \t".<font color=red>format<font color=black>(k, v)) | ||
+ | else: | ||
+ | <font color=red>print<font color=black>(<font color=blue>"'{}' = {} \t".<font color=red>format<font color=black>(k, v), end = ‘') | ||
+ | <font color=red>print<font color=black>() | ||
+ | <font color=green># 딕셔너리를 리스트로 내림차순 정렬 | ||
+ | <font color=black>fal = <font color=red>sorted<font color=black>(fa.items(), key = lambda x:x[1], reverse=True) | ||
+ | <font color=green># fa.items()의 딕셔너리의 키와 값의 세트가 끝날때까지 | ||
+ | # + x에 넣어주고 :을 기준으로 앞이 파라미터, 뒤가 리턴값 | ||
+ | # x의 1번째 인덱스 즉 개수를 가지고 내림차순정렬 | ||
+ | <font color=red>print<font color=green>(<font color=red>type<font color=black>(fal), <font color=blue>'>> 내림차순 출력'<font color=black>) | ||
+ | <font color=green># 이때 sorted함수는 리스트 내의 튜플이 들어간 형태로 반환 | ||
+ | <font color=black>cnt <font color=green>= 0 | ||
+ | for index in fal: | ||
+ | <font color=red>set<font color=black>(index) <font color=green># 튜플을 집합형 데이터로 변경 | ||
+ | <font color=black>cnt += 1 | ||
+ | if cnt % 3 == 0: | ||
+ | #print(" {} \t".format(i)) | ||
+ | <font color=red>print<font color=black>(<font color=blue>"'{}' = {} \t".<font color=red>format<font color=black>(index[0], index[1])) | ||
+ | else: | ||
+ | <font color=red>print(<font color=blue>"'{}' = {} \t"<font color=black>.<font color=red>format<font color=black>(index[0], index[1]), end=‘') | ||
+ | <font color=red>print<font color=black>() | ||
+ | pmsg = dec(msg) | ||
+ | print(pmsg) | ||
+ | if __name__ == <font color=blue>'__main__'<font color=black>: | ||
+ | main()<ref name="티스토리"> D4tai1, 〈[https://ccurity.tistory.com/265 Cipherxext Only Attack(암호문 단독 공격)구현]〉, 《티스토리》, 2019-05-31</ref> | ||
− | + | ===시연=== | |
− | + | d4tai1.@ubuntu ~/crypto/10week python3 COA.py | |
− | + | '5' = 12 '3' = 12 '%' = 16 | |
− | + | '#' = 8 '0' = 6 ')' = 16 | |
− | + | '6' = 11 '*' = 13 ';' = 26 | |
− | + | '4' = 19 '8' = 33 '2' = 5 | |
− | + | '=' = 1 '‘' = 3 '@' = 2 | |
− | # | + | '1' = 8 '(' 10 '?' = 3 |
− | + | 'c'' = 1 | |
− | + | (class 'list') >> 내림차순 출력 | |
− | + | '8' = 33 ';' = 26 '4' = 19 | |
− | + | '%' = 16 ')' = 16 '*' = 13 | |
− | + | '5' = 12 '6' = 11 '(' = 10 | |
− | + | '#' = 8 '1' = 8 '0' = 6 | |
+ | '2' = 5 '9' = 5 '3' = 4 | ||
+ | ':' = 4 '‘' = 3 '?' = 3 | ||
+ | '@' = 2 '-' = 2 '=' = 1 | ||
+ | 'c' = 1 | ||
+ | 53@@a305))6*the26)h%=')h%)te06*theae@60'))e5t1%(t:-%*eae3(ee)5*ath6(tee*96*?t | ||
+ | e)*%(the5)t5*a2:*%(th956*2(t*ch)e@e*th0692e5)t)6ae)h%%t1(%9the0e1te:e%1thheae5 | ||
+ | th')-he5a52ee06*e1(%9thet(eeth(%?3hthe)h%t161t:1eet%?t | ||
+ | d4tai1@unbuntu ~/crypto/10week | ||
+ | *통계적 성질을 이용해서 영어 문장에서 출현 빈도가 높은 순서대로 [e, t, a, o, i..]이다. | ||
+ | *이러한 부분이 확률이기 때문에 정확하지 않으므로 빈도수가 비슷할 경우 바꿔서도 공격 코드를 작성해 보아야 한다. | ||
+ | *이 공격은 [[암호문]]이 길수록 유리하다.<ref name="티스토리"></ref> | ||
− | + | {{각주}} | |
− | + | ||
− | + | == 참고자료 == | |
− | + | * laon, 〈[https://steemit.com/kr/@laon/6whr3f 암호분석의 분류]〉, 《스팀잇》 | |
− | + | * index-of, 〈[http://index-of.co.uk/Cryptology/01.pdf 제 1 장 암호알고리즘 개요]〉, 《개인 웹 사이트》 | |
− | : | + | * D4tai1, 〈[https://ccurity.tistory.com/265 Cipherxext Only Attack(암호문 단독 공격)구현]〉, 《티스토리》, 2019-05-31 |
− | + | ||
− | + | == 같이 보기 == | |
− | + | * [[암호해독]] | |
− | + | ||
− | + | {{암호 알고리즘|검토 필요}} | |
− | |||
− | |||
− | |||
− |
2019년 8월 1일 (목) 01:18 기준 최신판
암호문 단독공격(Ciphertext Only Attack; COA)이란 도청자가 알고리즘을 알고 있고, 암호문을 가로챌 수 있다는 가정하에 도청자가 어떤 암호문을 얻어서 대응되는 평문과 키를 찾는 공격을 말한다. 도청자는 암호문을 가지고 통계적 성질, 문장의 특성 등을 추정하여 해독하기 때문에, 가장 쉽게 적용될 수 있는 공격이다.
예를 들자면, 영어로 된 평문을 암호화시킨 암호문을 암호문 단독 공격으로 얻어냈을 때 영어에서 가장 많이 쓰이는 글자가 e이기 때문에 가장 많이 나오는 글자는 e일 것이라고 예측을 하는 것이다.[1]
개요[편집]
공격자가 가장 적은 정보를 가지고 공격하는 것을 암호문 단독 공격이라 한다. 이 공격에서 공격자는 같은 암호키를 사용하여 같은 알고리즘으로 암호화된 유한 암호문 집합만을 가지고 있다. 따라서 공격자의 목표는 대응되는 평문을 찾거나 사용된 암호키를 찾거나 암호 키를 찾지 못하였지만, 암호키 없이 암호문을 복호화할 수 있는 새로운 알고리즘을 발견하는 것이다. 기지 평문 공격에서 공격자는 암호문뿐만 아니라 대응되는 평문도 가지고 있다. 하지만 가지고 있는 암호문/평문 쌍을 공격자가 선택할 수 없다. 이 공격에서 공격자의 목표는 사용된 암호키를 찾거나 암호키를 찾지 못하였지만, 암호키 없이 암호문을 복호화할 수 있는 새로운 알고리즘을 발견하는 것이다.[2]
구현[편집]
msg = '53%%#305))6*;4826)4%=\')4%);806*;48#8@60\'))85;1%(;:-%*8#83(88)5*#;46(;88*96*?;8)*%(;485);5*#2:*%(;4956*2(5*c4)8@8*;4069285);)6#8)4%%;1(%9;48081;8:8%1;48#85;4\')-485#528806*81(%9;48;(88;4(%?34;48)4%;161;:188;%?;' # 메세지 내에서 어떤 문자가 몇 개 나왔는지.... # 빈도수를 체크하는 프로그램 # 구조는 딕셔너리[키(문자)에 대한 값(개수)]으로 구성 # 암호문만 알고 있을때 사용 가능!!! # 빈도수 많은 걸로 맞춰가는 것 외에 방법이 없음 def check(msg): fa = {} for c in msg: if c in fa: fa[c] += 1 else: fa[c] = 1 return fa def dec(msg): pmsg = for c in msg: # 통계적 기법을 이용하여 # 제일 많이 나온 순서대로 영문자 출현빈도수와 비교해서 치환 if c == '8': c = 'e' elif c == ';': c = 't' elif c =='4': c = 'h' elif c =='#': c = 'a' pmsg = pmsg + c # 치환한 문자로 문자열 생성 return pmsg def main(): fa = check(msg) cnt = 0 # 한 줄에 3개씩 출력 # 딕셔너리의 키와 값을 출력 for k, v in fa.items(): cnt += 1 if cnt % 3 == 0: print("'{}' = {} \t".format(k, v)) else: print("'{}' = {} \t".format(k, v), end = ‘') print() # 딕셔너리를 리스트로 내림차순 정렬 fal = sorted(fa.items(), key = lambda x:x[1], reverse=True) # fa.items()의 딕셔너리의 키와 값의 세트가 끝날때까지 # + x에 넣어주고 :을 기준으로 앞이 파라미터, 뒤가 리턴값 # x의 1번째 인덱스 즉 개수를 가지고 내림차순정렬 print(type(fal), '>> 내림차순 출력') # 이때 sorted함수는 리스트 내의 튜플이 들어간 형태로 반환 cnt = 0 for index in fal: set(index) # 튜플을 집합형 데이터로 변경 cnt += 1 if cnt % 3 == 0: #print(" {} \t".format(i)) print("'{}' = {} \t".format(index[0], index[1])) else: print("'{}' = {} \t".format(index[0], index[1]), end=‘') print() pmsg = dec(msg) print(pmsg) if __name__ == '__main__': main()[3]
시연[편집]
d4tai1.@ubuntu ~/crypto/10week python3 COA.py '5' = 12 '3' = 12 '%' = 16 '#' = 8 '0' = 6 ')' = 16 '6' = 11 '*' = 13 ';' = 26 '4' = 19 '8' = 33 '2' = 5 '=' = 1 '‘' = 3 '@' = 2 '1' = 8 '(' 10 '?' = 3 'c = 1 (class 'list') >> 내림차순 출력 '8' = 33 ';' = 26 '4' = 19 '%' = 16 ')' = 16 '*' = 13 '5' = 12 '6' = 11 '(' = 10 '#' = 8 '1' = 8 '0' = 6 '2' = 5 '9' = 5 '3' = 4 ':' = 4 '‘' = 3 '?' = 3 '@' = 2 '-' = 2 '=' = 1 'c' = 1 53@@a305))6*the26)h%=')h%)te06*theae@60'))e5t1%(t:-%*eae3(ee)5*ath6(tee*96*?t e)*%(the5)t5*a2:*%(th956*2(t*ch)e@e*th0692e5)t)6ae)h%%t1(%9the0e1te:e%1thheae5 th')-he5a52ee06*e1(%9thet(eeth(%?3hthe)h%t161t:1eet%?t d4tai1@unbuntu ~/crypto/10week
- 통계적 성질을 이용해서 영어 문장에서 출현 빈도가 높은 순서대로 [e, t, a, o, i..]이다.
- 이러한 부분이 확률이기 때문에 정확하지 않으므로 빈도수가 비슷할 경우 바꿔서도 공격 코드를 작성해 보아야 한다.
- 이 공격은 암호문이 길수록 유리하다.[3]
각주[편집]
- ↑ laon, 〈암호분석의 분류〉, 《스팀잇》
- ↑ index-of, 〈제 1 장 암호알고리즘 개요〉, 《개인 웹 사이트》
- ↑ 3.0 3.1 D4tai1, 〈Cipherxext Only Attack(암호문 단독 공격)구현〉, 《티스토리》, 2019-05-31
참고자료[편집]
- laon, 〈암호분석의 분류〉, 《스팀잇》
- index-of, 〈제 1 장 암호알고리즘 개요〉, 《개인 웹 사이트》
- D4tai1, 〈Cipherxext Only Attack(암호문 단독 공격)구현〉, 《티스토리》, 2019-05-31
같이 보기[편집]