일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- proc contents
- mutate()
- groupe_by()
- dplyr
- summarize()
- sample_n()
- arrange()
- distinct()
- filter()
- 대칭형 알고리즘
- select()
- samp;e_frac()
- AES
- Today
- Total
Gae Ko's Blog
2016 국가암호공모전 (Ⅱ-A) 분야 문제 01 문제 본문
2016 국가암호공모전 (Ⅱ-A) 분야 문제 01 문제.pdf
이 문제를 풀기 전에 RSA와 중국인의 나머지 정리에 대해 공부하였다.
이 문제를 풀고 이해하기에 필요한 정도로 설명하면 다음과 같다.
RSA - 공개키 암호 시스템으로 공개키와 개인키를 사용 - 공개키는 모두에게 알려져 있으며 암호화할 때 사용하고 개인키를 가진 자만이 암호화된 것을 복호화할 수 있음 - 키 생성 과정
이 때 확장된 유클리드 호제법을 사용하여 d를 구한다
- 암호화 : c = m^e mod n - 복호화 : m = c^d mod n |
중국인의 나머지정리 (CRT : Chinese Remainder Theorem) - 서로소인 자연수들에 대한 연립합동식의 유일한 해를 찾는 정리 - 정의 및 계산 방법은 다음과 같다.
k개의 서로소들 와 임의의 정수 a1, a2, ... , ak가 있을 때, 임의의 i (1 ≤ i ≤ k)에 대해 x ≡ ai (mod ni) 로 표현되는 변수 x의 연립합동방정식에 대해 성립하는 해는 유일하게 존재한다. 그 해를 어떻게 구할까?? 서로소인 음이 아닌 정수 에 대해서 라 하자. 각 에 대해서 와 는 서로소 이므로, 인 정수 가 항상 존재한다. ∵ 확장 유클리드호제법 라고 하면 다음이 성립한다. ei ≡ 0 (mod ni) ei ≡ 1 (mod nj) (i ≠ j) 여기서 라 하면 a ≡ ai (mod ni) ∀ i = 1, 2, ... ,k 이 성립하고 여기서 a 가 해가 된다. |
문제.
세 명의 사용자가 e = 3으로 고정하고 공개키를 각각 (3, n1), (3, n2), (3, n3)으로 설정한 후, 동일한 메시지 m에 대해 암호화(즉, c1 = m3 mod n1, c2 = m3 mod n2, c3 = m3 mod n3)를 수행한 결과가 각각 c1, c2, c3와 같을 때, m을 복원하시오.
n1 = 2310299443493285728875630082549132881822025540257530965759514012060264869125167678507394069856345219
n2 = 1640254853984465233890458607584621854508380697315386098130522602681990087093753900898805886346512517
n3 =3418519173916888863589816004190034375879476446746811141598913103396792921968768128979083353071236733
c1 = 852463884908235555765408734486025119365910986910875208826208737582871671723341488120300441323003770
c2 = 313555711879294064521282442285653226645699338301908834904362312223705316351738030120328187018289910
c3 = 3404239695295196799353493775777325699675748893697977348429335254042115834104851844221409452136061008
풀이.
문제 설명에 보면 '지나치게 작은 e를 사용하면 경우에 따라서 개인키 없이 평문이 복화화 될 수 있음'라는 힌트를 주어졌다. 그러므로 개인키를 직접 구하지 않고 복호화하는 방법에 대해 생각해보면 된다.
주어진 식들을 나열해보면 다음과 같다. 여기서 구하고자 하는 것이 m의 값임을 기억하자.
c1 = m^3 mod n1
c2 = m^3 mod n2
c3 = m^3 mod n3
( n1, n2, n3 : 두 소수의 곱, 세 수는 서로소)
중국인의 나머지 정리를 공부하고나서 문제를 봐서 그런지 바로 중국인의 나머지정리를 사용하여 m^3의 값을 구할 수 있음을 알 수 있었다.
위 연립합동식의 해에 대하여 중국인의 나머지 정리에 의해 식을 다음과 같이 세울 수 있다. (파란색은 주어진 값이며 빨간색은 주어지지 않은 값이다. )
m^3 ≡ c1*(n2n3*s1) + c2*(n1n3*s2) + c3*(n1n2*s3) (mod n1n2n3)
계산을 하고자 생각해보니 숫자가 너무 커서 불편하고 복잡하다.
간단한 식을 만들기 위해 가능한 나머지를 줄이자.
c2 < c1 < c3 이므로 제일 작은 c2값을 빼도 식의 성립에 아무런 지장이 없다.
(m^3 -c2) mod n1 = c1 - c2 = r1
(m^3 -c2) mod n2 = 0
(m^3 -c2) mod n3 = c3 - c2 = r2
m^3 ≡ r1*(n2n3*s1) + 0*(n1n3*s2) + r2*(n1n2*s3) + c2 (mod n1n2n3)
≡ r1*(n2n3*s1) + r2*(n1n2*s3) + c2 (mod n1n2n3) ---- ★
여기서 s1과 s3은 다음과 같다.
s1(n2n3) ≡ 1 (mod n1) 를 만족하는 s1 → s1은 mod n1에 대한 n2n3의 역원
s3(n1n2) ≡ 1 (mod n3) 를 만족하는 s3 → s3은 mod n3에 대한 n1n2의 역원
s1과 s3은 모듈러 연산의 곱에 대한 역원이고 확장 유클리드 알고리즘으로 모듈러에서의 곱셈의 역원을 구할 수 있다.
이 부분에서 많이 헤메었다. ㅠㅠ
복잡하게 생각하였지만 그런거 없이, 확장 유클리드 알고리즘을 사용하여 s1과 s3를 구하면 되는 것이었다!
구한 s1과 s3을 가지고 식(★)을 계산하면 m^3값을 구할 수 있다.
계산에 사용한 코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | n1 = 2310299443493285728875630082549132881822025540257530965759514012060264869125167678507394069856345219 n2 = 1640254853984465233890458607584621854508380697315386098130522602681990087093753900898805886346512517 n3 = 3418519173916888863589816004190034375879476446746811141598913103396792921968768128979083353071236733 c1 = 852463884908235555765408734486025119365910986910875208826208737582871671723341488120300441323003770 c2 = 313555711879294064521282442285653226645699338301908834904362312223705316351738030120328187018289910 c3 = 3404239695295196799353493775777325699675748893697977348429335254042115834104851844221409452136061008 r1 = c1 - c2 r2 = c3 - c2 def auth(e1, e2): # mod e2 에 대한 e1의 역원(승산 역원) a = [1,0] b = [0,1] x = e1 y = e2 i=2 if e1 > e2 : while x%y != 0: q ,tmp = divmod(x,y) x = y y = tmp a.append(a[i-2] - q*a[i-1]) b.append(b[i-2] - q*b[i-1]) i = i + 1 if a[i-1]*e1 + b[i-1]*e2 == 1: print "ok" if a[i-1] < 0: return a[i-1]+e2 return a[i-1] else: while y%x != 0: q ,tmp = divmod(x,y) y = x x = tmp a.append(a[i-2] - q*a[i-1]) b.append(b[i-2] - q*b[i-1]) i = i + 1 if a[i-1]*e2 + b[i-1]*e1 == 1: print "ok" if b[i-1] < 0: return b[i-1]+e2 return b[i-1] s1 = auth(n2*n3, n1) s3 = auth(n1*n2, n3) mm = (r1*(n2*n3*s1) + r2*(n1*n2*s3) + c2) % (n1*n2*n3) # m^3 print mm ## 출처 : https://m.blog.naver.com/PostView.nhn?blogId=sorx1234&logNo=220613536845&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F | cs |
'암호' 카테고리의 다른 글
ppt 대용 발표자료 (0) | 2018.08.03 |
---|---|
[암호] 해시함수 (0) | 2018.02.12 |
[암호] openssl를 이용한 RSA 암복호화 (0) | 2018.01.29 |
[암호] openssl로 파일을 암호화/복호화 하기 (0) | 2018.01.25 |
[암호] RSA 암호화 (0) | 2018.01.24 |