# 대칭 암호 vs 비대칭 암호

{% hint style="warning" %}
**목표: 이 문서의 목표는 대칭키 암호와 비대칭키 암호의 개념·특징·대표 알고리즘(AES, RSA)을 이해하고, 두 방식이 실제 시스템에서 어떻게 보안성과 성능을 동시에 만족시키는지 그 원리를 이해하는 데 있다.**
{% endhint %}

zkp 자체는 암호화가 아닌 **증명** 기술이지만, 실제 서비스에서 zkp를 쓰는 순간 대칭키/비대칭키 암호 위에서 동작한다.

예를 들어 사용자의 데이터 내역은 대칭키 암호로 암호화하고, 검증키 관리와 같은 것은 비대칭키 암호를 사용한 뒤, **이 암호화된 값들이 올바르게 계산되었다는 사실**을 zkp로 증명한다.

이 글에서는 zkp 자체를 설명하기에 앞서, 그 기저에 깔린 대칭키와 비대칭키 암호의 구조를 먼저 정리한다.

### **대칭키 암호란?**

대칭키 암호는 데이터의 암호화와 복호화에 **동일한 키**를 사용하는 암호화 방식이다. 즉, 평문을 암호화할 때 사용한 키를 암호문을 복호화할 때도 그대로 사용한다.

<figure><img src="/files/SqSGNXDhPDdNNJ9bd7EY" alt=""><figcaption><p>대칭키 특징</p></figcaption></figure>

#### **대칭키 암호의 특성**

대칭키 암호는 다음과 같은 특징을 가진다.

* **속도**: XOR, Bitwise, Substitution 등 비교적 간단한 연산을 기반으로 하므로, 비대칭키 암호 방식에 비해 연산 속도가 매우 빠르다.
* **확장성** : 빠른 속도 덕분에 대용량의 데이터를 암호화하는 데 효율적이다. 파일 암호화, 네트워크 트래픽 암호화 등에 널리 사용된다.

대칭키 암호는 데이터를 처리하는 방식에 따라 **스트림 암호**와 **블록 암호**로 나뉘며, 운용 모드에 따라 보안성과 동작 특성이 달라진다.

* **스트림 암호**
  * 데이터를 **비트 단위로 순차적**으로 암호화하는 방식이다.
  * 입력과 동시에 암호화가 이루어져 속도가 빠르고 하드웨어 구현이 간단하다.
  * ex) 실시간 스트리밍이나 무선 통신 등
* **블록 암호**
  * 평문을 **고정된 크기의 블록 단위**로 나누어 각 블록을 암호화한다.
  * 현대 암호 시스템에서 가장많이 사용하는 방식이며, 대표적으로 AES가 있다.
* **운용 모드** : 같은 블록 암호라도 어떻게 블록을 연결해서 쓸지에 따라 보안 성질이 달라진다.
  * **ECB**
    * 같은 평문 블록 → 항상 같은 암호문 블록
    * 평문 패턴이 그대로 드러나기 때문에 보안상 취약하다.
  * **CBC, CTR**
    * CBC는 IV, CTR은  nonce/counter를 사용해 같은 평문이라도 매번 다른 암호문을 도출한다.
  * **GCM**

    * GCM은 CTR 기반으로 암호화하면서, 추가로 인증 태그를 생성하는 AEAD 방식이라 암호화와 무결성을 모두 만족한다.

#### **대칭키 알고리즘의 예시 AES**

AES는 현재 가장 널리 사용되는 표준 블록 암호 알고리즘으로,

* 블록 크기 : **128비트**
* 키 길이 : **128 / 192 / 256비트** (AES-128 / AES-192 / AES-256)

를 사용한다.

AES는 **비페이스텔 구조**를 가지며, 입력된 데이터 블록을 4x4 **상태행렬**로 변환하여 처리한다.

<figure><img src="/files/ZipyRVt3i7vKgAAEmy4Q" alt=""><figcaption><p>4x4 상태행렬</p></figcaption></figure>

암호문 과정을 여러번의 라운드로 구성되며, 각 라운드는 다음 네 가지 연산을 순차적으로 수행하여 데이터의 혼돈과 확산을 충족시킨다.

> **실제 AES에서는** 초기 AddRoundKey를 한 번 수행한 뒤, 중간 라운드에서는 네 가지 연산을 모두 수행하고, 마지막 라운드에서는 MixColumns를 생략한다.

**(1) SubBytes**

* 상태 행렬의 각 바이트를 아래와 같은 S-Box라는 정해진 치환 테이블을 이용해 치환한다.
* 이 과정을 통해 비선형성을 도입하여, 키와 평문 사이의 관계를 복잡하게 만들고 암호의 혼돈을 제공한다.

<div data-full-width="false"><figure><img src="/files/eybPuLV94CTy31nvTlwq" alt=""><figcaption><p>SubBytes 예시</p></figcaption></figure></div>

**(2) ShiftRows**

* 상태 행렬의 각 행을 정해진 규칙에 따라 왼쪽으로 순환 이동시키는 과정이다.
  * 0번째 행 : 0바이트 이동(이동 없음)
  * 1번째 행 : 1바이트 이동
  * 2번째 행 : 2바이트 이동
  * 3번째 행 : 3바이트 이동
* 이 연산은 바이트들의 위치를 섞어 확산에 기여한다.

<figure><img src="/files/ruc8Rl957HKioUY7YMW5" alt=""><figcaption><p>ShiftRows 예시</p></figcaption></figure>

**(3) MixColumns**

* 상태 행렬의 각 열을 특정한 행렬과 곱셈 연산을 수행한다.
* 한 바이트가 바뀌면 전체 열의 값이 모두 바뀌도록 설계되어 있어, 한 비트의 변화가 전체 블록에 영향을 미치게 된다.

다음과 같이 상태 행렬의 한 열 $$s\_0, s\_1, s\_2, s\_3$$ 가 주어질 때 특정한 행렬과 XOR 연산을 진행한다.

<figure><img src="/files/5dJvZLFotWMYFO2o1ZfQ" alt=""><figcaption><p>MixColumns 예시</p></figcaption></figure>

<figure><img src="/files/hswcuY6J3ygiwz9DpCzT" alt=""><figcaption><p>행렬 곱셈 식 전개</p></figcaption></figure>

**(4) AddRoundKey**

* 현재 상태 행렬과, 해당 라운드에서 생성된 라운드 키를 XOR 연산으로 합치는 과정이다.
* 이 단계에서 실제 키 값이 암호화 연산에 반영된다.
* 키 길이에 따라 라운드 수는 다음과 같이 달라진다.
  * **AES-128 : 10 라운드**
  * **AES-192 : 12라운드**
  * **AES-256 : 14라운드**

<figure><img src="/files/aH1gnGJG377zGW2Qcntw" alt=""><figcaption><p>AddRoundKey 예시</p></figcaption></figure>

#### **대칭키 실제 활용 예시**

* **네트워크 트래픽 암호화 (TLS/SSL)**
  * 웹 브라우저와 서버 간 HTTPS 통신에서 최초 핸드셰이크 때 비대칭키로 세션 키를 교환하고, 이후 실제 데이터 전송은 AES-GCM 같은 대칭키로 암호화한다.
* **저장 데이터 암호화**
  * 데이터베이스와 같은 곳에 데이터 저장 시 AES를 사용해 데이터를 암호화한다.

#### **대칭키 암호의 한계**

* **키 분배 문제**
  * 대칭키는 양쪽이 같은 비밀 키를 미리 안전하게 공유해야 한다.
  * 이 키 자체를 어떻게 안전하게 교환할지(키 교환 문제)가 어렵다.
  * 실제로는 Diffie–Hellman, RSA 같은 비대칭키를 이용해 세션 키를 교환하는 하이브리드 방식을 사용한다.
* **키 관리**
  * 사용자, 서버, 서비스 개수가 늘어날수록 서로 공유해야 하는 키의 개수가 기하급수적으로 증가한다.
  * 조직 규모가 커질수록 키를 생성·배포·갱신·폐기하는 키 관리 인프라가 필요해진다.
* **무결성·인증 부재**

  * 순수한 대칭키 암호화는 기밀성을 보장할 뿐, 송신자에 대한 무결성은 보장하지 않는다.
  * 이를 보완하기 위해 MAC(HMAC), AEAD(AES-GCM 등) 방식으로 무결성과 송신자 인증까지 함께 제공하는 구조를 사용한다.

### **비대칭키 암호란?**

비대칭키 암호는 데이터의 암호화와 복호화에 서로 다른 키를 사용하는 방식이다.

* 공개키 (Public Key)
  * 누구에게나 공개해도 되는 키
* 개인키 (Private Key)
  * 소유자만 알고 있어야 하는 키

이 두 키는 수학적으로 밀접한 관계를 가지며, 다음과 같은 특징이 존재한다.

* **공개키로 암호화한 데이터 → 해당 개인키로만 복호화 가능**
* **개인키로 서명한 데이터 → 해당 공개키로만 검증 가능**

<figure><img src="/files/3ldG9f9dnkcf9X5r6pWK" alt=""><figcaption><p>비대칭키 특징</p></figcaption></figure>

#### **비대칭키 암호의 특성**

* **키 교환의 안전성**
  * 대칭키와 달리, 비밀 키를 직접 주고받을 필요가 없다.
  * 공개키만 상대에게 전달하면 되므로 키 교환 문제를 근본적으로 완화한다.
* **속도**
  * 소인수분해나 이산 로그 문제 등 복잡한 수학적 연산을 기반으로 하므로 대칭키 암호에 비해 연산 속도가 느리고, 비용이 크다.
* **인증**

  * 개인키로 데이터를 서명하면, 해당 개인키와 쌍을 이루는 공개키로 서명을 검증할 수 있다. 이를 통해 메시지를 보낸 사람이 누구인지 인증하는 **디지털 서명** 기능을 구현할 수 있다.
  * 블록체인 트랜잭션 서명, 코드 서명, 전자 문서 서명 등에서 활용된다.

#### **비대칭키 알고리즘의 예시 RSA**

RSA는 **큰 숫자를 소인수분해하기 어렵다는 수학적 원리**에 기반한 대표적인 비대칭키 알고리즘이다.

**(1) 키 생성**

1. 먼저 매우 큰 두 개의 서로 다른 소수 $$p$$와 $$q$$를 선택한다.
2. $$n = p\*q$$을 계산한다.
3. 오일러 피 함수 값인 $$\phi(n) = (p-1)(q-1)$$을 계산한다.
4. $$1 < e < \phi(n)$$ 범위에서 $$gcd(e, \phi(n)) = 1$$인 정수 $$e$$를 선택한다.
5. $$d\*e \equiv 1$$  $$(mod$$ $$\phi(n))$$를 만족하는 $$d$$를 구한다. ($$d$$는 $$e$$의 모듈러 역원이다.)

* 공개키 : $$(e, n)$$
* 개인키 : $$(d, n)$$

**(2) 암호화 / 복호화**

* 메시지를 정수 $$m$$으로 표현했을 때,

  * 암호화: $$c \equiv m^e$$ $$(mod$$ $$n)$$
  * 복호화 : $$m \equiv c^d$$ $$(mod$$ $$n)$$

**(3) 암호화 및 복호화 원리**

평문 $$m = 9$$, 공개키 $$= (91, 5)$$, 개인키 $$= (91, 29)$$를 암복호화하면 다음과 같다.

* $$c \equiv m^e$$ $$(mod$$ $$n)$$
* $$81 = 9^5$$ $$(mod$$ $$91)$$

암호문 $$c$$는 81이 나온다.

복호화는 다음과 같이 진행한다.

* $$m \equiv c^d$$ $$(mod$$ $$n)$$
* $$9 = 81^{29}$$ $$(mod$$ $$n)$$

평문이 올바르게 9로 복호화가 된다.

복호화의 원리는 오일러 정리로 설명될 수 있으며, 오일러 정리는 다음을 만족한다.

$$m$$와 $$n$$이 서로소일 때, $$m^{\phi(n)}$$은 1과 합동이다.

* $$m^{\phi(n)} \equiv 1$$ $$(mod$$ $$n)$$

RSA에서 공개키와 개인키는 다음을 만족한다.

* $$e\*d \equiv 1$$ $$(mod$$ $$\phi(n))$$

따라서 어떤 정수 k에 대해 다음과 같이 표현이 가능하다.

* $$e\*d = 1 +k \* \phi(n)$$

복호화 과정은 다음과 같이 전개된다.

* $$m = c^d$$ $$(mod$$ $$n)$$
* $$m^{e\*d}$$ $$(mod$$ $$n)$$
* $$m^{1+k\*\phi(n)}$$$$(mod$$ $$n)$$
* $$m*m^{k*\phi(n)}$$$$(mod$$ $$n)$$
* $$m\*m^{\phi(n)\*k}$$$$(mod$$ $$n)$$
  * 오일러 정리에 의해 m과 n이 서로소이므로 $$m^{\phi(n)}$$ $$(mod$$ $$n)$$은 1과 합동이다.
* $$m\*1^k$$$$(mod$$ $$n)$$
* $$m$$ $$mod$$ $$n$$

평문이 올바르게 도출된 것을 확인할 수 있다.

#### **비대칭키 실제 활용 예시**

* **키 분배/교환** : 실제로는 공개키 암호로 안전하게 대칭키만 전송하고, 실제 데이터 암호화는 빠른 대칭키로 수행한다.
* **디지털 서명** : 신뢰 기반 인증, 무결성 인증, 부인방지에 활용한다.

#### 비대칭키 암호의 한계

* **성능 한계**
  * 느리고 연산 비용이 크므로,

    주로 작은 데이터(세션 키, 해시 값)에만 사용한다.
* **키 길이 관리**
  * 같은 보안 수준을 맞추기 위해

    대칭키에 비해 **훨씬 긴 키 길이**가 필요하다.

    (ex,  AES-128 ≈ RSA-3072 정도의 보안 강도 추정)
* **실제 사용 구조**
  * 실제 시스템에서는 보통 다음과 같은 구조를 사용한다.

    1. 비대칭키(RSA, DH, ECDH 등)로 **대칭키(세션 키) 교환**
    2. 그 이후 모든 실제 데이터는 대칭키(AES 등)로 암호화

### **결론**

결론적으로, **대칭키 암호**는 **효율적인 데이터 보호**에, **비대칭키 암호**는 **안전한 키 관리와 인증**에 각각 강점을 가진다.

대칭키 암호와 비대칭키 암호는 **서로 보완적인 관계**에 있으며,

실제 보안 시스템에서는 **상호 보완적 형태**로 함께 사용되며, 이를 통해 **보안성**과 **성능**을 동시에 확보한다.

### Reference

1. <https://www.crypto101.io/>
2. <https://en.wikipedia.org/wiki/RSA_cryptosystem>
3. <https://csrc.nist.gov/pubs/fips/197/final>
4. <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf>
5. <https://en.wikipedia.org/wiki/Advanced_Encryption_Standard>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://upsidezkp.gitbook.io/upside-zkp-docs/step-0/prerequisite/vs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
