이전 글 Elliptic Curve Cryptography(ECC)에서는 타원곡선 암호의 특징 및 알고리즘을 알아보았다.
이번에는 이를 활용한 암호화 응용과 실제 사용 예를 살펴보기로 한다.
ECC vs. RSA공개키 암호화 방법으로 RSA와 비교하여 이야기 되나, 실제적으로 ECC는 RSA와 동일한 기능으로 사용하지는 않는다.
정확히는 RSA가 아니라 이산대수 문제를 이용한 DH 나 DSA 용도로 사용한다고 말할 수 있다.
RSA의 경우 아래와 같이 평문 $k$ 를 공개키 $e$로 모듈러 지수 연산을 하는 형식이다.
$$ E = k^e \pmod{n} $$
타원 곡선(Elliptic Curve)는 일반적으로 생각하는 가로 세로비가 다른 길쭉한 원을 말하는 것이 아니라 다음과 같은 공식으로 구성된 곡선을 말한다.
$$y^2 = x^3 + ax + b$$
$a$ 와 $b$ 는 임의의 수로 특이점이 없도록 다음과 같은 조건을 만족하여야 한다.
$$4 a^3 + 27b^2 \neq 0$$
이와 같은 조건을 만족하는 곡선은 다음과 같은 모양을 가진다.
b=1, a=2~-3 일 때의 모양
만일 위 조건을 만족하지 않는 경우는 아래와 같이 첨 점이거나 교차하는 특이점이 있다.
Hash 함수란 임의의 길이의 데이타를 축약하여 고정된 길이의 데이타로 매핑하는 함수를 말한다.
데이타 검색을 위한 hash 함수, 데이타 손상을 검출하기 위한 CRC32 도 hash 함수 이지만, 이 글에서 언급하는 것은 암호화 해시 함수이다.
각 용도에 따라서 해시 함수의 특성은 다음처럼 다를 수 있다.
데이터 검색용: 모든 입력 데이타에 대해서 hash 결과값이 균등 분포를 가져야 한다. 데이타 손상 검출용: 원하는 비트 개수 까지의 오류에 대해서 정확히 검출되어야 하고, 알고리즘에 따라서 제한된 비트 개수 까지 오류 복원이 가능하여야 한다.
DSA는 Digital Signature Algorothm 의 약자로, 미국 NIST 에서 제정한 디지털 서명 알고리즘이다.
이번 글에서는 이와 같은 디지털 서명에 관한 전반적인 사항을 다음과 같은 순서로 정리한다.
RSA 서명 알고리즘 ElGamal 서명 알고리즘 DSA 서명 알고리즘 OpenSSL 을 이용한 동작 확인 RSA SignatureRSA 서명 방식은 앞의 RSA 글에서 언급한 것과 같이 개인키로 문서의 Hash 값을 암호화 하는 것으로 RSA의 동작 원리를 알고 있으면 직관적이다. 관련 표준은 PKCS#1의 8장 을 보면 된다.
지난 번에 설명한 이산대수를 이용하면 RSA 의 기본원리도 쉽게 이해할 수 있다.
RSA는 이름에 특별한 의미는 없고, 알고리즘을 발명한 사람들(Ron Rivest, Adi Shamir, Leonard Adleman)의 약자를 따서 만든 것이다.
AES와는 달리 공개키(public key)와 개인키(private key) 두 벌로 구성된 키를 가지고 있는 비대칭키 암호화 알고리즘이다.
가장 일반적인 사용용도는 다음과 같이 Bob 이 Alice에게 암호 데이타 전달하는 방법이다.
Alice의 공개키는 공개되어 누구나 알수 있다. Bob은 Alice의 공개키를 이용하여 암호화 하여 일반 채널로 전달한다.
지난 번에 설명한 이산대수를 이용하여 Diffie-Hellman Key Exchange(DHKE, 키교환 또는 키합의)을 이해해 보자.
TLS 암호화 채널을 절차를 간단하게 보면 다음과 같다.
서버를 믿을 수 있는지 검증, 필요시 클라이언트도 인증 RSA 암호화 채널로 키를 전달하거나, Diffie-Hellman 방식으로 키교환 교환한 키로 AES, ChaCha20와 같은 대칭키로 암호화 Diffie-Hellman은 여기서 두번째 대칭키를 교환하는 방법이다.
RSA와 같은 비대칭키를 이용하여 암호화 채널을 만든 후 이를 이용하여 대칭키를 전달하는 것은 직관적이다. 하지만 Diffie-Hellman 방식은 이와 같은 암호화 채널 없이도, 서로 키를 교환할 수 있는 방식이다.
키 합의, 비대칭키는 역연산이 실제적으로 불가능한 수학적 이론을 기반으로 만들어진 알고리즘이기 때문에, 이의 기본 동작을 이해하기 위해서는 수학적인 지식이 어느정도 필요하다.
여기에서는 이들 알고리즘의 동작 원리에 필요한 최소한의 수학을 정리해본다.
타원알고리즘을 제외하고, 키합의와 비대칭키 알고리즘을 이해하기 위해서는 다음과 같은 것을 알아야 한다.
소인수 분해 유클리드 호제법을 이용하여 두 수의 최대 공약 수 찾기 확장 유클리드 호제법으로 소수 모듈로 연산에서 곱하기 역원 찾기 페르마 소정리를 이용하여 소수 모듈로의 지수 연산 역원 찾기 오일러 정리를 이용하여 일반 모듈로에서 지수 역원 찾기 소인수 분해임의의 정수를 소인수 분해하는 데에는 효과적인 방법이 없다.
일정 데이터 단위로 암호화를 하는 블럭 암호와 비교하여 스트림 암호(Stream Cipher)는 비트 또는 바이트 단위로 암호화를 하는 방식이다.
쉽게 말해서 블럭 암호는 키를 사용하여 (필요하면 IV도 포함해서) 블럭단위로 전치와 치환을 통하여 암호하를 가하는 방식이라고 할 수 있다. 이와 비교하여 스트림 암호는 키와 IV(Initial Vector)로 다양한 연산을 이용하여 난수열을 만들고, 이를 이용하여 평문과 XOR 과정을 통하여 암호화를 하는 것이다. 블럭 암호에서 설명한 AES-CTR와 같은 것이 이와 같은 난수열을 만드는 방법 중 하나이다.
이전 글의 Block Cipher(블럭암호) 암호화 방법을 그대로 사용하기에는 몇가지 문제가 있다 (아래 내용에서는 AES로 표기하나, 다른 블럭암호 방식에 공통적인 사항이다).
우선 첫번째 문제는 공격자가 암호키를 몰라도 암호 블럭을 순서를 바꾸어나 다른 내용으로 바꿀 수 있다는 것이다. AES 암호의 경우 128bits(16bytes) 단위로 암호화 되는데, 예를 들어 다음과 같은 거래 정보를 암호화 한다고 해보자.
1 2 3 4 5 6 7 8 9 10 11 struct { char from[16]; char to[16]; char amount[16]; } transaction; struct transaction tx = { .
암호 알고리즘은 암호화/복호화 작업을 동일한 키 하나로 사용하는지, 아니면 암호화하는 키(공개키)와 복호화 하는 키(개인키)를 따로 사용하는지에 따라 각각 대칭키(Symmetric Key), 비대칭키(Asymmetric Key) 방식으로 나뉜다.
graph TD; subgraph Symmetric Key A1([평문]) --> B1[암호화 모듈] --> C1([암호문]) K1([키]) --> B1 C2([암호문]) --> B2[복호화 모듈] --> A2([평문]) K1 --> B2 end subgraph Asymmetric Key A3([평문]) --> B3[암호화 모듈] --> C3([암호문]) K2([공개키]) --> B3 C4([암호문]) --> B4[복호화 모듈] --> A4([평문]) K3([개인키]) --> B4 end style B1 fill:#FFF9C4 style B2 fill:#FFF9C4 style B3 fill:#FFF9C4 style B4 fill:#FFF9C4 대칭키는 암호화 할때 일정 블럭 크기(예를 들어 128bits)를 한번에 암호화 할지, 아니면 비트/바이트 단위로 암호화 하는지에 따라서 블럭 암호(Block Cipher), 스트림 암호(Stream Cipher) 로 구분한다.