많은 고전 암호에서는 송신자와 수신자가 같은 키를 가지고 있어야 했습니다. 이처럼 송신자와 수신자가 같은 키를 공유해야 하는 암호 시스템을 대칭키 암호 시스템(Symmetric key cryptosystem)이라고 부릅니다.
같은 키를 공유하는 특성상, 대칭키 암호 시스템은 사전에 서로 키를 공유하는 과정이 반드시 필요합니다. 그러나 현대에 많은 데이터가 오가는 네트워크는 도청에 매우 취약하므로 키를 평문으로 공유하기는 부적절합니다. 그래서 외부인이 키가 공유되는 과정을 도청해도, 공유되는 키는 알지 못하게 하는 키 공유 알고리즘(Key exchange algorithm)을 연구하였습니다.
1970년 중반에 Diffie와 Hellman이 Diffie-Hellman 키 교환 알고리즘을 제시하였고, 송신자와 수신자가 서로 다른 키를 사용하는 공개키 암호 시스템(Public key cryptosystem)의 개념을 창안했습니다. 이는 대칭키와 대비되어 비대칭키 암호 시스템(Asymmetric cryptography)이라고도 불립니다.
대칭키 암호 시스템은 암호화와 복호화에 같은 키를 사용하는 암호 시스템입니다. 크게 블록 암호와 스트림 암호로 구분합니다.
블록 암호(Block cipher)는 평문을 정해진 크기의 블록 단위로 암호화하는 암호입니다. 예를 들어 블록의 크기가 4바이트라면 평문을 4바이트의 블록으로 쪼개어 각 블록마다 암호화를 진행합니다. 이 때 평문의 크기가 블록 크기의 배수가 아니라면 평문 뒤에 패딩을 추가합니다. 블록 암호의 대표적인 예시로는 DES 대칭키 암호와 AES 대칭키 암호가 있습니다.
스트림 암호(Stream cipher)는 송신자와 수신자가 공유하는 데이터 스트림을 생성하고 이를 평문과 특정한 연산을 수행하여 암호문을 생성하는 암호입니다. 복호화 과정은 암호화 과정의 연산을 역으로 수행하여 진행됩니다.
대부분의 상황에서는 암호화 과정과 복호화 과정에 XOR 연산(⊕)을 사용합니다. 평문을 P, 암호문을 C, 스트림을 X라 할 때 암호문 C는 C = P ⊕ X
로 생성됩니다.
X ⊕ X = 0
이므로 양 변에 X를 XOR 연산하는 것으로 복호화를 할 수 있습니다.
만약 송신자와 수신자가 평문 길이만큼의 스트림을 안전하게 공유할 수 있으면 스트림이 아닌 평문을 공유하면 되므로 암호화가 필요하지 않은 환경입니다. 그래서 일반적으로 송신자와 수신자는 암호문을 공유하는 대신 시드(Seed)라고 불리는 값을 공유하고, 이를 사전에 합의된 함수의 인자로 넣어서 스트림을 각자 생성해 사용합니다.
공개키 암호 시스템에서 송신자는 수신자의 공개키(Public key)로 데이터를 암호화하여 수신자에게 전송하고, 수신자는 자신의 비밀키(Private key)로 이를 복호화합니다. 같은 시스템에서 사용되는 공개키와 비밀키를 키 쌍(Key Pair)이라고 부릅니다.
공개키는 모두에게 공개되어 있으므로 공개키를 아는 사람은 누구나 수신자에게 암호문을 보낼 수 있습니다. 하지만 개인키는 수신자만 알고 있으므로, 공격자는 암호문을 도청해도 이를 복호화할 수 없습니다.