RSA — 공개키 암호의 수학적 구조

Division Theorem, GCD, Modular Arithmetic, Euler 정리, Fermat 정리, CRT — 지금까지 쌓아온 정수론의 모든 도구가 RSA 하나를 위해 수렴한다. 큰 소수 두 개의 곱을 되돌리기 어렵다는 사실 하나가 최초의 실용적 공개키 암호를 낳았고, 40여 년이 지난 지금도 웹의 인증서와 전자서명을 떠받치고 있다.

이 포스트에서 다루는 내용
  • RSA 키: n=pqn = pq (공개), ee (공개 지수), dd (개인 지수), ed1(modφ(n))ed \equiv 1 \pmod{\varphi(n)}
  • 암복호화: C=memodnC = m^e \bmod nm=Cdmodn=medmodnm = C^d \bmod n = m^{ed} \bmod n
  • 복호화 정확성: medm(modn)m^{ed} \equiv m \pmod{n}gcd(m,n)=1\gcd(m,n)=1이면 오일러 정리, 아니면 페르마+CRT
  • 보안 근거: ϕ(n)\phi(n)dd를 구하는 것은 소인수분해와 동치, RSA 문제 자체의 어려움은 미해결
  • 고속 지수연산: Square-and-Multiply — 지수의 값 kk에 비례하던 비용을 자릿수 logk\log k에 비례하게

대칭키 vs 공개키 암호

대칭키(Secret Key) 시스템: 송신자와 수신자가 동일한 키 kk를 공유한다. 두 사람만 알면 되지만, NN명이 통신하려면 (N2)\binom{N}{2}개의 키가 필요하고 키 배포 자체가 문제가 된다.

공개키(Public Key) 시스템: 암호화 키 ee는 모두에게 공개하고, 복호화 키 dd만 비밀로 유지한다. NN명이 통신할 때 각자 키 쌍 하나만 있으면 된다. 단, 공개된 ee로부터 dd를 계산하는 것이 불가능해야 한다.

RSA는 대표적인 공개키 암호 시스템이다.

RSA 설정

키 생성:

  1. 큰 소수 pp, qq를 선택한다. (pqp \neq q)
  2. n=pqn = pq (공개, modulus)
  3. ϕ(n)=ϕ(pq)=(p1)(q1)\phi(n) = \phi(pq) = (p-1)(q-1) (비공개)
  4. 1<e<ϕ(n)1 < e < \phi(n)이고 gcd(e,ϕ(n))=1\gcd(e, \phi(n)) = 1ee 선택 (공개 지수)
  5. ed1(modϕ(n))ed \equiv 1 \pmod{\phi(n)}dd 계산 (비공개 — 확장 유클리드 알고리즘)

공개키: (n, e)(n,\ e) · 개인키: (p, q, d, ϕ(n))(p,\ q,\ d,\ \phi(n))

RSA 구조 — 키 구성과 암복호화 흐름
RSA 구조 — 키 구성과 암복호화 흐름

암호화: 평문 mm (0m<n0 \leq m < n)에 대해

C=memodnC = m^e \bmod n

복호화: 암호문 CC에 대해

m=Cdmodnm = C^d \bmod n

왜 ed ≡ 1 (mod φ(n)) 인가

핵심은 지수 연산의 주기성이다.

오일러 정리에 의해 gcd(a,n)=1\gcd(a, n) = 1이면 aϕ(n)1(modn)a^{\phi(n)} \equiv 1 \pmod{n}이므로, 지수 연산의 관점에서 ϕ(n)0\phi(n) \equiv 0이다. 즉 지수는 mod ϕ(n)\bmod\ \phi(n)으로 환산된다.

aiajai+ja(i+j)modϕ(n)(modn)a^i \cdot a^j \equiv a^{i+j} \equiv a^{(i+j) \bmod \phi(n)} \pmod{n}

복호화가 원래 평문을 돌려주려면 medm1(modn)m^{ed} \equiv m^1 \pmod{n}이어야 하므로, 지수 부분에서

ed1(modϕ(n))ed \equiv 1 \pmod{\phi(n)}

이 조건이 필요하다.

복호화 정확성 증명 — m^(ed) ≡ m (mod n)

ed=1+kϕ(n)ed = 1 + k\phi(n)으로 쓰면 med=m(mϕ(n))km^{ed} = m \cdot (m^{\phi(n)})^k이다.

Case 1: gcd(m, n) = 1

오일러 정리에 의해 mϕ(n)1(modn)m^{\phi(n)} \equiv 1 \pmod{n}이므로,

med=m1k=m(modn)m^{ed} = m \cdot 1^k = m \pmod{n} \quad \checkmark

Case 2: gcd(m, n) = p (또는 q)

n=pqn = pq이고 m<nm < n이므로 gcd(m,n)\gcd(m, n)11, pp, qq, nn 중 하나다. m=0m = 0인 경우는 자명하고, pp인 경우를 증명하면 qq인 경우도 대칭이다.

m=pxm = px로 쓸 수 있다. CRT를 적용해 mod p\bmod\ pmod q\bmod\ q로 분리한다.

mod p 검증: m0(modp)m \equiv 0 \pmod{p}이므로

med0ed0m(modp)m^{ed} \equiv 0^{ed} \equiv 0 \equiv m \pmod{p} \quad \checkmark

mod q 검증: m=pxm = px이고 pqp \neq q (둘 다 소수)이므로 gcd(m,q)=1\gcd(m, q) = 1. 페르마의 소정리에 의해 mq11(modq)m^{q-1} \equiv 1 \pmod{q}. 이때

ed1(mod(p1)(q1))    ed=1+k(p1)(q1)ed \equiv 1 \pmod{(p-1)(q-1)} \implies ed = 1 + k(p-1)(q-1)

(q1)(q-1)(p1)(q1)(p-1)(q-1)을 나누므로,

ed1+k(p1)(q1)1(modq1)ed \equiv 1 + k(p-1)(q-1) \equiv 1 \pmod{q-1}

따라서

medm1m(modq)m^{ed} \equiv m^1 \equiv m \pmod{q} \quad \checkmark

CRT로 결합: medm(modp)m^{ed} \equiv m \pmod{p}이고 medm(modq)m^{ed} \equiv m \pmod{q}이며 gcd(p,q)=1\gcd(p,q)=1이므로,

medm(modn)m^{ed} \equiv m \pmod{n} \quad \checkmark
쉽게 말하면

RSA 복호화가 정확히 원래 메시지를 돌려주는 이유는 "거듭제곱의 주기성" 덕분이다. ee번 거듭제곱해서 암호화하고, dd번 거듭제곱해서 복호화하면, eded번 거듭제곱한 셈인데 — 오일러 정리에 의해 이것이 정확히 1번 거듭제곱한 것과 같아진다. 즉 원래 메시지로 돌아온다.

보안 근거 — 소인수분해 문제

dd를 복원하려면 ed1(modϕ(n))ed \equiv 1 \pmod{\phi(n)}을 풀어야 한다. 이를 위해서는 ϕ(n)=(p1)(q1)\phi(n) = (p-1)(q-1)이 필요하다.

ϕ(n)\phi(n)nn으로부터 구하는 것은 nn을 소인수분해하는 것과 동등하다. y=ϕ(n)=pqpq+1y = \phi(n) = pq - p - q + 1을 알면,

ny+1=p+q,n=pqn - y + 1 = p + q, \quad n = pq

p+qp + qpqpq를 알면 pp, qq를 이차방정식으로 구할 수 있다. 따라서 ϕ(n)\phi(n)을 아는 것과 nn을 소인수분해하는 것은 동치이다.

소인수분해의 판정 버전(“nnkk보다 작은 소인수가 있는가”)은 NP ∩ co-NP 에 속한다. yes에 대한 증거는 그런 소인수 하나이고, no에 대한 증거는 모든 소인수가 kk 이상임을 보이는 완전한 소인수분해다. 어느 쪽이든 다항식 시간에 검증된다. 그리고 현재까지 다항식 시간 알고리즘은 알려져 있지 않다.

따라서 다음을 공개하고 나머지를 숨긴다.

  • 공개: nn, ee
  • 비공개: pp, qq, dd, ϕ(n)\phi(n)
"인수분해와 동치"라는 말이 어디까지 참인가

RSA를 깨는 길이 하나가 아니므로, 무엇이 인수분해와 동치인지를 나눠 봐야 한다.

할 수 있게 되는 일인수분해와의 관계
ϕ(n)\phi(n)을 구한다동치. 위에서 이차방정식으로 보였다
dd를 구한다동치. (n,e,d)(n, e, d)에서 nn을 인수분해하는 알고리즘이 알려져 있다
주어진 CC에서 mm을 복원한다미해결. 인수분해할 수 있으면 복원할 수 있지만, 그 역은 알려져 있지 않다

세 번째 줄이 핵심이다. “CC에서 mm을 복원하라”는 문제를 RSA 문제라 부르는데, 이것이 인수분해만큼 어렵다는 것은 증명된 적이 없다. 오히려 지수 ee가 작은 경우에는 인수분해를 RSA 문제로 되돌리는 특정 형태의 환원이 존재한다면 그 자체로 효율적인 인수분해 알고리즘이 나온다는 결과가 있어, 그런 환원을 찾기 어려우리라는 쪽에 무게가 실린다.

그래서 정확히 말하면 RSA의 안전성은 인수분해의 어려움이 아니라 RSA 문제의 어려움이라는 별도의 가정 위에 선다. 인수분해가 어렵다는 것은 그 가정의 필요조건이다. 인수분해가 뚫리면 RSA도 뚫리지만, 인수분해가 어렵다고 해서 RSA 문제가 어렵다는 보장은 아직 없다.

모듈러 지수연산 (Square-and-Multiply)

암호화 C=memodnC = m^e \bmod n과 복호화 m=Cdmodnm = C^d \bmod n은 지수만 다를 뿐 같은 연산이다. 그래서 일반화해 aa를 지수 kk번 거듭제곱하는 akmodna^k \bmod n 을 어떻게 계산할지 본다.

지수의 크기는 두 방향에서 크게 다르다. ee는 관례상 65537 =216+1= 2^{16}+1을 써서 17비트에 불과하지만, dd는 2048비트 RSA에서 약 2048비트에 달한다. 비용이 문제가 되는 쪽은 복호화다.

aakk번 곱하는 직접 계산은 곱셈이 k1k-1번 필요하다. 여기서 kk지수의 값이지 비트 수가 아니다. dd가 2048비트라면 k22048k \approx 2^{2048}이므로 우주가 끝날 때까지 끝나지 않는다.

핵심 아이디어: kk를 이진수로 펼치면 O(logk)O(\log k)번의 곱셈으로 끝난다. logk\log k는 곧 지수의 비트 수이므로, 지수의 값에 비례하던 비용이 자릿수에 비례하는 비용으로 바뀐다.

알고리즘 (MSB → LSB):

  1. 지수 kk의 최상위 비트부터 시작해 result = a로 초기화
  2. 이후 각 비트에 대해:
    • 항상: result = result² mod n (제곱)
    • 비트 = 1이면 추가: result = result × a mod n (곱셈)
Square-and-Multiply — 17^23 단계별 계산
Square-and-Multiply — 17^23 단계별 계산

예시 172317^{23}에서 23=10111223 = 10111_2: 총 7회 곱셈 (4회 제곱 + 3회 ×a\times a). 직접 계산의 22회 대비 3배 이상 절약.

복호화 지수 dd가 2048비트라면 직접 계산은 약 220482^{2048}번이지만, Square-and-Multiply는 제곱 약 2048번과 곱셈 약 1024번(11인 비트가 절반쯤이므로), 즉 3000여 번으로 충분하다. 각 단계에서 mod n을 함께 적용하므로 수의 크기도 nn 미만으로 유지된다.

적절한 p, q 선택

ppqq를 아무렇게나 선택하면 공격에 취약해진다.

pq|p - q|가 작을 때: pqnp \approx q \approx \sqrt{n}이면, n\sqrt{n} 근처 값들을 검색해 pp, qq를 쉽게 찾을 수 있다 (Fermat 인수분해 공격).

p1p - 1이 작은 소인수만 갖는 경우: Pollard의 p1p-1 알고리즘에 취약하다. p1p-1의 소인수가 모두 어떤 한계 BB 이하라면 p1p-1K=lcm(1,2,,B)K = \text{lcm}(1, 2, \ldots, B)를 나눈다. 그러면 페르마 소정리로 aK1(modp)a^{K} \equiv 1 \pmod p이므로 paK1p \mid a^K - 1이고, gcd(aK1, n)\gcd(a^K - 1,\ n)을 계산하면 pp가 그대로 떨어져 나온다. q1q-1에 대해서도 같다.

현재 권장 기준:

  • pp, qq: 각 1024비트 이상 → nn: 2048비트 이상
  • pq|p - q|: 충분히 클 것
  • p1p - 1, q1q - 1: 큰 소인수를 포함할 것
핵심 정리
  • RSA는 ed1(modφ(n))ed \equiv 1 \pmod{\varphi(n)}을 이용해 medm(modn)m^{ed} \equiv m \pmod{n}을 성립시킨다 — 오일러 정리가 핵심이다.
  • gcd(m,n)1\gcd(m, n) \neq 1인 예외 케이스도 modp\bmod pmodq\bmod q를 분리한 페르마+CRT 접근으로 성립함을 증명할 수 있다.
  • ϕ(n)\phi(n)을 구하는 것과 dd를 구하는 것은 각각 소인수분해와 동치다. 다만 "CC에서 mm을 복원한다"가 소인수분해만큼 어려운지는 미해결이다. 인수분해의 어려움은 RSA 안전성의 필요조건이지 충분조건이 아니다.
  • Square-and-Multiply로 지수연산이 O(k)O(k)에서 O(logk)O(\log k)로 줄어든다. 여기서 kk는 지수의 이고 logk\log k비트 수다. 2048비트 지수도 3000여 번 연산으로 처리된다.

요약

RSA는 세 가지 수학적 사실 위에 서있다.

첫째, ed1(modϕ(n))ed \equiv 1 \pmod{\phi(n)}이라는 조건 하에 medm(modn)m^{ed} \equiv m \pmod{n}이 성립한다 — 오일러 정리의 직접적인 귀결이다. 둘째, ϕ(n)\phi(n)을 알려면 n=pqn = pq를 소인수분해해야 하므로, nnee만 공개해도 dd는 감추어진다. 셋째, Square-and-Multiply로 수천 비트 지수연산도 O(loge)O(\log e) 만에 처리할 수 있어 실용적이다.

남은 질문은 하나다: 실제로 큰 소수를 어떻게 찾는가? RSA 키 생성에서 1024비트 이상의 소수 두 개가 필요한데, 이 크기에서 소수인지 판별하는 직접적인 방법은 현실적으로 불가능하다. 다음 글 Find Prime에서 Fermat 테스트와 확률적 소수 탐색 알고리즘을 다룬다.

© 2026 XsQuare01. Powered by GitHub Pages. · 방문자