암호학의 하이브리드 암호화 방식

LinuxBeginner
지금 연습하기

소개

암호화의 세계에서 우리는 종종 속도와 보안 사이의 상충 관계 (trade-off) 에 직면합니다. AES 와 같은 대칭 암호화 알고리즘은 매우 빠르며 대량의 데이터를 암호화하는 데 이상적이지만, 송신자와 수신자 모두에게 안전하게 배포되어야 하는 공유 비밀 키 (shared secret key) 가 필요합니다. RSA 와 같은 비대칭 암호화 알고리즘은 공개/개인 키 쌍 (public/private key pair) 을 사용하여 안전한 키 교환에 탁월하지만, 계산 집약적이며 대량의 데이터를 암호화하기에는 너무 느립니다.

하이브리드 암호화 (Hybrid encryption) 는 이 두 가지 방법의 장점을 결합하여 이 문제를 해결합니다. 이는 "두 세계의 장점 (best of both worlds)"을 활용하는 접근 방식을 사용합니다.

  1. 비대칭 암호화는 임시적인 일회용 대칭 키 (종종 "세션 키 (session key)"라고 불림) 를 안전하게 암호화하고 공유하는 데 사용됩니다.
  2. 그런 다음 대칭 암호화는 이 세션 키를 사용하여 실제 대용량 메시지 데이터를 빠르고 효율적으로 암호화하는 데 사용됩니다.

본 실습에서는 openssl 명령줄 도구를 사용하여 처음부터 완전한 하이브리드 암호화 체계를 구현합니다. RSA 키 쌍을 생성하고, 무작위 AES 세션 키를 생성하며, RSA 를 사용하여 세션 키를 암호화하고, AES 를 사용하여 메시지를 암호화한 다음, 마지막으로 이 과정을 역순으로 진행하여 메시지를 복호화하게 됩니다.

하이브리드 암호화 개요

이 단계에서는 하이브리드 암호화를 강력하고 널리 사용되는 기술로 만드는 핵심 개념들을 간략하게 검토할 것입니다. 이 단계에서는 실행할 명령이 없으며, 실습을 시작하기 전에 견고한 개념적 기반을 구축하는 것이 목표입니다.

대칭 암호화 (예: AES)

  • 작동 방식: 암호화와 복호화 모두에 단일 공유 비밀 키를 사용합니다.
  • 장점: 매우 빠르고 효율적이어서 대용량 파일이나 데이터 스트림을 암호화하는 데 완벽합니다.
  • 단점: 키 분배 (Key distribution) 문제입니다. 공유 비밀 키를 수신자에게 안전하게 전달하는 방법은 무엇일까요? 공격자가 키를 가로채면 모든 통신 내용을 복호화할 수 있습니다.

비대칭 암호화 (예: RSA)

  • 작동 방식: 암호화를 위한 공개 키 (public key) 와 복호화를 위한 개인 키 (private key) 의 두 가지 키 쌍을 사용합니다. 공개 키는 자유롭게 공유할 수 있지만, 개인 키는 소유자가 비밀로 유지해야 합니다.
  • 장점: 키 분배 문제를 해결합니다. 누구나 귀하의 공개 키를 사용하여 귀하에게 보낼 메시지를 암호화할 수 있지만, 귀하의 개인 키로만 복호화할 수 있습니다.
  • 단점: 수학적으로 복잡하여 대칭 암호화보다 훨씬 느립니다. 대량의 데이터를 암호화하는 데는 비실용적입니다.

하이브리드 솔루션

하이브리드 암호화는 이 두 가지 방법을 결합하여 비대칭 암호화의 보안성과 대칭 암호화의 속도를 모두 얻습니다. 일반적인 작업 흐름은 다음과 같습니다.

  1. 송신자 (앨리스) 가 수신자 (밥) 에게 안전한 메시지를 보내려고 합니다.
  2. 앨리스는 새롭고 무작위적인 대칭 세션 키를 생성합니다.
  3. 앨리스는 이 빠른 대칭 세션 키를 사용하여 실제 메시지를 암호화합니다.
  4. 앨리스는 밥의 공개 키를 얻습니다. 그녀는 이 키를 사용하여 작고 작은 대칭 세션 키만 암호화합니다.
  5. 앨리스는 대칭으로 암호화된 메시지와 비대칭으로 암호화된 세션 키를 모두 밥에게 보냅니다.
  6. 밥은 두 항목을 수신합니다. 그는 먼저 자신의 개인 키를 사용하여 암호화된 세션 키를 복호화합니다.
  7. 이제 밥이 원래의 대칭 세션 키를 확보했으므로, 이를 사용하여 실제 메시지를 빠르게 복호화합니다.

이 프로세스는 대량의 데이터가 효율적으로 암호화되도록 보장하며, 해당 암호화에 사용된 키는 최대의 보안으로 교환됩니다. 다음 단계에서는 이 정확한 작업 흐름을 구현할 것입니다.

RSA 및 AES 키 생성

이 단계에서는 하이브리드 암호화 체계에 필요한 두 가지 유형의 키, 즉 비대칭 부분을 위한 RSA 키 쌍 (공개 및 개인) 과 대칭 부분을 위한 무작위 세션 키를 생성합니다. 모든 작업은 ~/project 디렉토리에서 수행됩니다.

먼저, 2048 비트 RSA 개인 키를 생성하겠습니다. 이 키는 수신자가 비밀로 유지해야 합니다.

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

키가 생성되는 동안 일부 출력이 표시됩니다. 다음으로 방금 생성한 개인 키에서 해당 공개 키를 추출해야 합니다. 이 공개 키는 암호화된 메시지를 보내려는 모든 사람과 공유할 수 있습니다.

openssl rsa -pubout -in private_key.pem -out public_key.pem

이 명령은 writing RSA key를 출력할 것입니다.

이제 무작위 256 비트 (32 바이트) 세션 키를 생성해 보겠습니다. 이 키는 AES 알고리즘과 함께 실제 데이터를 암호화하는 데 사용됩니다. 암호학적으로 강력한 난수 데이터를 생성하고 처리를 용이하게 하기 위해 Base64 로 인코딩하기 위해 openssl rand를 사용합니다.

openssl rand -base64 32 > session_key.key

방금 생성한 키를 확인하기 위해 디렉토리의 파일을 나열해 보겠습니다.

ls -l

설정 중에 생성된 message.txt 파일과 함께 방금 생성한 세 가지 키 파일이 표시되어야 합니다.

-rw-rw-r-- 1 labex labex   57 Oct 20 15:12 message.txt
-rw------- 1 labex labex 1704 Oct 20 15:14 private_key.pem
-rw-rw-r-- 1 labex labex  451 Oct 20 15:14 public_key.pem
-rw-rw-r-- 1 labex labex   45 Oct 20 15:14 session_key.key

RSA 를 사용하여 세션 키 암호화

이 단계에서는 하이브리드 암호화 프로세스의 중요한 부분인 대칭 세션 키 암호화를 수행합니다. 오직 의도된 수신자만이 세션 키를 사용할 수 있도록 보장하기 위해, 우리는 수신자의 RSA 공개 키를 사용하여 이를 암호화할 것입니다.

공개 키 작업을 위한 유틸리티인 openssl pkeyutl 명령을 사용할 것입니다. 이 명령을 사용하여 public_key.pem으로 session_key.key 파일을 암호화할 것입니다.

다음 명령을 실행하십시오:

openssl pkeyutl -encrypt -pubin -inkey public_key.pem -in session_key.key -out encrypted_session_key.bin

이 명령을 분석해 보겠습니다:

  • pkeyutl: 공개 키 유틸리티 도구입니다.
  • -encrypt: 암호화 작업을 수행하겠다는 것을 지정합니다.
  • -pubin: 입력 키 (-inkey) 가 공개 키임을 나타냅니다.
  • -inkey public_key.pem: 암호화에 사용할 공개 키를 지정합니다.
  • -in session_key.key: 암호화할 입력 파일 (우리의 AES 세션 키) 입니다.
  • -out encrypted_session_key.bin: 암호화된 키가 저장될 출력 파일입니다.

이 명령은 세션 키가 암호화된 형식으로 포함된 새 파일인 encrypted_session_key.bin을 생성합니다. 이 파일은 이제 해당 개인 키 소유자만이 복호화할 수 있으므로 안전하게 전송될 수 있습니다.

새로 생성된 파일을 확인해 보겠습니다:

ls -l encrypted_session_key.bin

암호화된 키가 포함된 바이너리 파일을 보게 될 것입니다.

-rw-rw-r-- 1 labex labex 256 Oct 20 15:14 encrypted_session_key.bin

AES 를 사용하여 데이터 암호화

세션 키를 안전하게 확보했으므로, 이제 원래의 암호화되지 않은 세션 키를 사용하여 주요 데이터 파일인 message.txt를 빠르게 암호화할 수 있습니다. 이 작업을 위해 AES-256-CBC 대칭 암호 (cipher) 를 사용할 것입니다.

openssl enc 명령은 키 (key) 와 초기화 벡터 (Initialization Vector, IV) 를 16 진수 (hexadecimal) 형식으로 제공해야 합니다. 우리의 session_key.key는 Base64 형식이므로, 먼저 이를 디코딩하여 16 진수로 변환해야 합니다. 또한 무작위 IV 를 생성할 것입니다. 편의를 위해 둘 다 환경 변수에 저장하겠습니다.

먼저, 세션 키를 변환하여 AES_KEY 변수에 저장합니다:

export AES_KEY=$(cat session_key.key | base64 -d | xxd -p -c 32)

다음으로, 128 비트 (16 바이트) 무작위 IV 를 생성하여 AES_IV 변수에 저장합니다. IV 는 동일한 평문 (plaintext) 을 여러 번 암호화할 때 서로 다른 암호문 (ciphertext) 이 생성되도록 보장하는 데 사용됩니다.

export AES_IV=$(openssl rand -hex 16)

키와 IV 가 준비되었으므로, 이제 openssl enc를 사용하여 message.txt를 암호화할 수 있습니다:

openssl enc -aes-256-cbc -in message.txt -out encrypted_message.dat -K $AES_KEY -iv $AES_IV

명령 옵션을 검토해 보겠습니다:

  • -aes-256-cbc: CBC 모드의 AES-256 암호를 지정합니다.
  • -in message.txt: 입력 데이터 파일입니다.
  • -out encrypted_message.dat: 암호화된 데이터의 출력 파일입니다.
  • -K $AES_KEY: 16 진수 형식의 암호화 키입니다 (대문자 K).
  • -iv $AES_IV: 16 진수 형식의 초기화 벡터입니다.

이 시점에서 송신자는 encrypted_message.dat, encrypted_session_key.bin, 그리고 IV ($AES_IV) 를 패키징하여 수신자에게 전송하게 됩니다. 이 실습 (lab) 에서는 복호화 단계를 위해 모든 파일이 디렉토리에 준비되어 있습니다.

암호화된 데이터 파일이 생성되었는지 확인해 보겠습니다:

ls -l encrypted_message.dat
-rw-rw-r-- 1 labex labex 64 Oct 20 15:14 encrypted_message.dat

메시지 복호화

마지막 단계에서는 수신자의 동작을 시뮬레이션해 보겠습니다. 수신자는 암호화된 데이터 (encrypted_message.dat), 암호화된 세션 키 (encrypted_session_key.bin), 그리고 IV 를 받았습니다. 그들은 자신의 비밀 개인 키 (private key) 를 사용하여 프로세스를 역으로 진행하고 원래 메시지를 복구할 것입니다.

먼저, 수신자는 자신의 private_key.pem을 사용하여 세션 키를 복호화해야 합니다.

openssl pkeyutl -decrypt -inkey private_key.pem -in encrypted_session_key.bin -out decrypted_session_key.key

이 명령은 -decrypt 플래그와 개인 키를 사용하여 pkeyutl을 실행하고 원래 AES 세션 키를 복구하여 decrypted_session_key.key에 저장합니다.

복호화된 키가 2 단계에서 생성한 원래 키와 동일한지 빠르게 확인할 수 있습니다. 파일이 동일하면 diff 명령은 아무런 출력도 생성하지 않아야 합니다.

diff session_key.key decrypted_session_key.key

이제 세션 키를 확보했으므로 주요 메시지를 복호화할 수 있습니다. 암호화 단계와 마찬가지로, 먼저 키를 16 진수 형식으로 변환해야 합니다.

export DECRYPTED_AES_KEY=$(cat decrypted_session_key.key | base64 -d | xxd -p -c 32)

마지막으로, 암호화에 사용된 것과 동일한 키와 IV 를 제공하면서 -d (복호화) 플래그와 함께 openssl enc를 사용합니다. (이전 단계에서 $AES_IV 변수는 셸에 여전히 설정되어 있습니다).

openssl enc -d -aes-256-cbc -in encrypted_message.dat -out decrypted_message.txt -K $DECRYPTED_AES_KEY -iv $AES_IV

프로세스가 완료되었습니다! 원래 메시지가 복구되어 decrypted_message.txt에 저장되었습니다. 성공을 확인하기 위해 그 내용을 보겠습니다.

cat decrypted_message.txt

터미널에 원래의 비밀 메시지가 출력되는 것을 볼 수 있어야 합니다:

This is a secret message that needs to be sent securely.

요약

본 실습 (lab) 에서 여러분은 OpenSSL 을 사용하여 완전한 하이브리드 암호화 및 복호화 워크플로우를 성공적으로 구현했습니다. 여러분은 우리의 디지털 통신 대부분을 보호하는 근본적인 개념들에 대해 실질적인 경험을 쌓았습니다.

여러분은 다음을 배웠습니다:

  • 비대칭 암호화 (asymmetric encryption) 를 위해 RSA 키 쌍을 생성하는 방법.
  • 대칭 암호화 (symmetric encryption) 를 위해 무작위 AES 세션 키를 생성하는 방법.
  • RSA 공개 키를 사용하여 세션 키를 안전하게 암호화하는 방법.
  • AES 세션 키를 사용하여 대용량 데이터를 효율적으로 암호화하는 방법.
  • RSA 개인 키로 세션 키를 복호화하고 이어서 데이터를 복호화하여 프로세스를 역순으로 진행하는 방법.

키 교환을 위한 비대칭 암호화의 보안성과 데이터 암호화를 위한 대칭 암호화의 속도를 결합하는 이 "두 세계의 장점을 모두 취하는 (best of both worlds)" 접근 방식은 매일 인터넷에서 여러분의 데이터를 보호하는 TLS/SSL과 같은 현대 보안 프로토콜의 초석입니다.