RSA 원리와 안전한 사용: 작은 수 예제부터 OAEP·PSS까지
1장 개념과 보호 목표#
RSA는 큰 정수의 모듈러 거듭제곱을 활용하는 공개키 기술입니다. 공개키와 개인키를 구분하지만 실제 암호화와 서명은 목적에 맞는 별도의 인코딩·패딩 스킴을 사용해야 합니다. 교과서의 식을 그대로 구현하면 안전한 RSA 시스템이 되지 않습니다.
2장 원리와 구분#
교육용으로 p=11, q=13을 고르면 n=143, φ(n)=120입니다. e=7, d=103이면 e×d는 120으로 나눈 나머지가 1입니다. 메시지 5를 암호화한 값은 5^7 mod 143=47이며 47^103 mod 143=5로 복원됩니다. 작은 수는 원리를 보여줄 뿐 실제 보안 수준을 제공하지 않습니다.
3장 비교와 판단 기준#
| 구분 | 교육용 값 | 의미 |
|---|---|---|
| 소수 | p=11, q=13 | 실무 보안에는 부적합한 작은 값 |
| 모듈러스 | n=143 | 공개키와 개인키 연산에 사용 |
| 지수 | e=7, d=103 | e×d ≡ 1 mod 120 |
| 변환 | 5 → 47 → 5 | 거듭제곱과 나머지 연산의 예시 |
4장 공개키와 개인키가 하는 일부터 나눈다#
공개키 암호화에서는 수신자의 공개키로 보호하고 수신자의 개인키로 복원합니다. 서명에서는 작성자의 개인키로 서명값을 만들고 공개키로 검증합니다. 키 방향만 외우면 서명을 개인키 암호화로 오해하기 쉽습니다. 실제로는 서로 다른 목적과 인코딩 규칙을 사용합니다.
RSA의 모듈러스 n은 공개될 수 있지만 이를 구성하는 소수와 개인 연산에 필요한 값은 보호해야 합니다. 공개키가 공개되었다는 사실은 사고가 아니며 개인키의 노출과는 다른 상황입니다. 어느 공개키가 어느 상대의 것인지는 인증서나 신뢰하는 배포 경로로 확인합니다.
5장 RSA의 키 생성 관계를 순서대로 계산한다#
교육용 p=11, q=13에서 n=143과 φ(n)=120을 구합니다. 120과 서로소인 e=7을 고르고 7×d≡1 mod 120을 만족하는 d=103을 구합니다. 공개 연산의 지수와 개인 연산의 지수가 역원 관계를 이루는 예시입니다. 실제 키 생성은 큰 안전한 파라미터와 검증된 난수·라이브러리를 사용합니다.
p=11, q=13
n=p×q=143
φ(n)=(p−1)(q−1)=120
e=7
d=103 → 7×103=721 → 721 mod 120=16장 암호화 계산을 작은 거듭제곱으로 분해한다#
5^7을 그대로 계산하지 않고 반복 제곱과 나머지를 사용하면 중간 값의 크기를 줄일 수 있습니다. 5^2 mod 143=25, 5^4 mod 143=53이며 5^7은 5^4×5^2×5의 곱에 해당합니다. 결과는 47입니다. 이 계산이 큰 지수의 모듈러 거듭제곱을 구현하는 기본 생각으로 이어집니다.
5^2 mod 143 = 25
5^4 mod 143 = 625 mod 143 = 53
5^7 mod 143 = 53×25×5 mod 143 = 47큰 수가 등장해도 같은 관계를 효율적으로 계산할 수 있습니다. 반대로 암호문에서 비밀 지수를 모른 채 역으로 값을 찾는 문제의 어려움과 구현의 안전성을 함께 고려해야 실제 보안이 됩니다.
7장 교과서 RSA를 그대로 쓰면 무엇이 빠질까#
원시 RSA는 결정적이며 메시지의 구조와 연산 관계를 노출할 수 있습니다. 암호문이 변형되었을 때 어떤 값을 내놓는지까지 안전하게 설계한 암호화 스킴이 필요합니다. 입력이 작거나 반복된다는 이유로 계산이 쉬워 보이더라도 운영에서는 원시 연산을 API로 제공하지 않습니다.
RSA-OAEP와 RSA-PSS는 안전한 사용을 위한 서로 다른 규칙입니다. OAEP는 암호화, PSS는 서명에 연결합니다. 라이브러리에서 단순히 RSA라는 이름의 함수를 고르는 것이 아니라 키 용도·해시·패딩 설정과 상대의 지원을 맞춰야 합니다.
flowchart TB
R["RSA 수학 연산"] --> O["OAEP 인코딩과 암호화"]
R --> S["PSS 인코딩과 서명"]
O --> C["수신자만 메시지 복원"]
S --> V["공개키로 서명 검증"]
C --> X["기밀성의 목적"]
V --> Y["무결성과 서명자 키 확인의 목적"]8장 OAEP의 입력 길이를 직접 판단한다#
모듈러스가 2048비트면 길이 k는 256바이트입니다. SHA-256의 출력은 32바이트이므로 OAEP 평문 최대 길이 k−2hLen−2는 190바이트입니다. 2048이라는 비트 수를 2048바이트 입력 한도로 착각하면 안 됩니다. 이 예시는 한도를 설명하며 해당 환경에 필요한 키 강도의 권고를 대신하지 않습니다.
큰 파일을 작은 조각으로 나누어 RSA만 반복하는 방식은 순서·누락·무결성 문제를 새로 만듭니다. RSA는 데이터 키 등의 작은 값을 보호하고 데이터 본문에는 인증된 대칭키 암호를 적용하는 구조가 일반적인 설계 출발점입니다.
9장 문서 하나를 하이브리드 방식으로 보호하기#
먼저 안전한 난수로 DEK를 만들고 문서를 AEAD로 암호화합니다. DEK를 받는 사람의 RSA 공개키와 OAEP로 감싼 뒤 암호문과 필요한 메타데이터를 전달합니다. 수신자는 개인키로 DEK를 복원하고 문서의 태그를 확인합니다. 파일 내용과 키 보호의 역할이 분리됩니다.
flowchart LR
D["문서"] --> A["DEK로 AEAD 암호화"]
K["무작위 DEK"] --> A
A --> C["문서 암호문과 태그"]
K --> R["수신자 공개키로 OAEP"]
R --> W["감싼 DEK"]
C --> P["전달 패키지"]
W --> P10장 여러 수신자에게 같은 파일을 전달하려면#
문서 본문을 한 번 암호화하고 DEK를 각 수신자의 공개키로 감싸는 구성이 가능합니다. 수신자 목록과 각 키 ID를 관리하고 권한이 없는 사람의 키 포장을 추가하는 경로를 제한해야 합니다. 전송 패키지의 무결성과 업무 인가도 함께 설계합니다.
수신자가 이미 복호화한 평문을 나중에 회수할 수 있다는 뜻은 아닙니다. 키 포장을 제거하는 행위와 이미 공유한 데이터의 복사본을 없애는 행위는 구분해야 합니다. 공유 범위와 보유기간 정책이 별도로 필요합니다.
11장 전자서명은 문서의 진실성을 보장할까#
서명은 정해진 데이터가 해당 개인키로 서명되었고 검증된 이후 변경되지 않았음을 확인하는 근거입니다. 서명자가 올바른 신원인지와 주장한 내용이 사실인지는 별도의 신뢰와 검토가 필요합니다. 만료·폐지·서명 시점의 검증 요구도 사용 목적에 따라 달라집니다.
서명할 바이트를 명확히 정하고 상대가 동일한 바이트를 검증하도록 해야 합니다. 문서를 다시 직렬화하거나 개행·인코딩을 바꾸면서 서명한 원본과 다른 값을 검증하는 오류를 피합니다.
12장 개인키 파일에는 소수와 CRT 값이 있을 수 있다#
개인키 형식은 빠른 개인 연산을 위해 p·q와 CRT 관련 값을 포함할 수 있습니다. 해당 값이 있다는 사실을 잘못된 저장 방식이라고 판단하지 않습니다. 오히려 그 파일 전체가 민감한 비밀임을 이해하고 접근·백업·로그·복사본을 보호해야 합니다.
CRT 기반 연산에서도 오류·부채널 방어가 필요합니다. 검증된 라이브러리의 보호 기능을 사용하고 직접 연산을 최적화하거나 실패 결과를 노출하는 코드를 추가할 때는 안전성 영향을 검토해야 합니다.
13장 암호화 키와 서명 키를 분리하면 무엇이 좋아질까#
서명 담당 서비스가 문서 복호화 키까지 필요로 하지 않도록 권한을 나눌 수 있습니다. 교체 주기·보존 요구·인증서 용도와 사고 영향도 분리하기 쉽습니다. 같은 키가 기술적으로 두 연산에 쓰일 수 있다는 사실과 실제 프로토콜·운영 정책이 허용한다는 판단은 다릅니다.
| 항목 | 암호화 키 | 서명 키 |
|---|---|---|
| 대표 사용 | 수신 데이터 복원 | 문서·배포 산출물 서명 |
| 외부 공개 값 | 수신자 공개키 | 검증자에게 제공할 공개키 |
| 유출 영향 | 해당 데이터의 기밀성 | 위조 서명의 가능성 |
| 관리 초점 | 과거 암호문·복구 | 서명 승인·검증·회수 |
14장 패딩 실패와 키 교체의 시험#
정상 메시지뿐 아니라 잘못된 키·손상된 포장·미지원 파라미터·길이 초과·손상된 서명을 시험합니다. 실패가 내부 비밀이나 구체적인 패딩 차이를 드러내지 않는지 확인하고, 오류가 난 데이터를 정상 빈 값으로 처리하지 않습니다.
키 교체에서는 새 공개키로 신규 데이터를 처리하면서 이전 암호문을 어떤 키로 읽을지 정합니다. 개인키 폐기 전에 과거 파일과 백업의 복구 요구를 확인해야 합니다. 큰 키를 새로 만든 것만으로 이미 노출된 과거 키와 데이터의 영향이 없어지지는 않습니다.
15장 적용 사례와 운영 방법#
실무 암호화는 RSA-OAEP와 대칭키 암호를 조합하는 하이브리드 방식을 검토하고, 서명에는 RSA-PSS 등 정해진 스킴을 사용합니다. RSA로 큰 파일 전체를 직접 암호화하지 않습니다. 개인키 형식은 성능 최적화를 위해 p·q 등 CRT 파라미터를 포함할 수 있습니다. 개인키 파일 전체를 비밀로 보호해야 합니다.
16장 RSA 수식과 실제 암호 스킴의 차이#
원시 RSA는 같은 입력에 같은 결과를 만드는 결정적 연산입니다. 이를 그대로 암호화 API로 노출하면 메시지 구조와 대수적 성질을 공격자가 이용할 수 있습니다. OAEP는 암호화용 인코딩, PSS는 서명용 인코딩이며 서로 대체하는 옵션이 아닙니다. API에서 해시·패딩·키 용도를 명확히 지정하고 상대 시스템과 같은 규칙으로 맞춰야 합니다.
OAEP가 처리할 수 있는 평문의 최대 길이는 모듈러스 길이를 k바이트, 해시 출력 길이를 hLen바이트라고 할 때 k−2×hLen−2입니다. 예를 들어 RSA 2048비트와 SHA-256 조합은 256−64−2=190바이트입니다. 이 계산은 입력 한도의 예시이며 특정 환경의 권장 보안 수준을 정하는 근거는 아닙니다.
17장 파일 암호화는 데이터 키와 나눠 처리한다#
대용량 문서는 무작위로 만든 데이터 키를 이용해 AEAD로 암호화하고, 데이터 키를 RSA-OAEP로 감싸는 구조를 사용할 수 있습니다. 받는 쪽은 개인키로 데이터 키를 복원한 뒤 태그를 검증하고 문서를 읽습니다. 암호문에 알고리즘과 키 버전 정보를 남기고, 변조된 키 포장이나 잘못된 패딩은 민감한 차이를 드러내지 않는 실패 경로로 처리합니다.
키 강도, 개인키 접근 권한, 패딩 오류 처리, 라이브러리의 부채널 방어는 함께 점검해야 합니다. 작은 수로 계산하는 연습과 운영 키 생성은 구분하고 운영에서는 검증된 구현의 키 생성 기능을 사용합니다.
18장 적용 전 확인할 사항#
- 원시 RSA 연산 대신 목적별 안전한 API를 사용한다
- 키 생성에 암호학적 난수를 사용한다
- 암호화용 키와 서명용 키의 용도·접근 권한을 구분한다
19장 자주 묻는 질문#
전자서명은 개인키로 문서를 암호화하는 것인가요?#
RSA 연산의 유사성 때문에 그렇게 비유하기도 하지만 실제 서명은 메시지를 인코딩해 검증 가능한 서명값을 만드는 절차입니다. 기밀성을 제공하는 암호화와 구분해야 합니다.
RSA 키를 서명과 암호화에 함께 써도 되나요?#
기술적으로 가능한 구성과 운영상 적절한 구성은 다릅니다. 용도별 키를 분리하면 권한·교체 주기·사고 영향을 분리하기 쉬우며 적용 프로토콜의 요구사항도 확인해야 합니다.
RSA로 파일을 여러 조각으로 나눠 직접 암호화하면 되나요?#
임의의 분할 암호화는 순서·무결성·처리 한도 문제를 새로 만듭니다. 표준화된 하이브리드 암호 구조와 안전한 상위 API를 사용하는 편이 적절합니다.