Linux #20
암호화(Encryption)
평문(plain text) 메시지나 데이터를 송수신 할 때 송수신자만 이해할 수 있도록 원문 메시지나 데이터를 변형시켜서 암호문(cipher text)으로 만드는 작업을 암호화로 부르는데 파일 단위(파일)의 암호화와 파일시스템 단위(하드디스크: Windows 11의 Bit Locker 같은 것)의 암호화를 사용할 수 있다.
굉장히 복잡하고 고급 수학이 들어간 암호학(Cryptographic)을 여기서 다루지는 않고 정보보안 과정에서 필요한 내용을 중심으로 알아보자.
Linux에서 파일을 암호화할 때 보통 GPG(Gnu Privacy Guard)를 이용하는데 GPG는 미국 내에서만 사용할 수 있는 PGP(Pretty Good Privacy) 암호화 기법과 호환되며 공유키 암호화와 공개키 암호화에서 모두 사용될 수 있다. SSL에 관련된 인증서(CRT) 키를 생성할 때 오픈소스 openssl 명령어를 사용하듯이, 개인키/공유키에 관련된 키를 생성할 때에 오픈소스 gpg 명령어를 사용한다.
이들 암호화 알고리즘은 보통 Feistel 기법을 사용하는데 블록 암호의 일종으로 특정 계산 함수를 반복해서 암호화가 이루어진다. 이 때 각 과정에 사용되는 함수를 라운드 함수라고 부르는데 많은 블록 암호가 파이스텔 구조를 가지고 있다. 예를 들어 (3)DES, Blowfish, SEED 등이 파이스텔 구조를 가진다.
◾ 송신자가 평문장 데이터나 메시지를 일정한 수학적 알고리즘(키)로 암호화(encryption)해서 암호문으로 보내면, 즉, 송신자가 '평문장 =>알고리즘(평문장+키) =>암호문'으로 만들어서 보내면
◾ 수신자는 동일한 알고리즘(키)을 사용해서 이를 복호화(decryption)해서 다시 평문장으로 만들어서 보게 된다. 즉, 수신자는 '암호문 =>알고리즘(암호문+키) =>평문장'으로 변환해서 읽는 프로세스이다.
◾ 암호화(encrypted)와 복호화(decrypted)에 동일한 키를 사용하면 '대칭키(symmetric) 암호화', 서로 다른 키를 사용하면 '비 대칭키(asymmetric) 암호화'로 부른다.
대칭키
대칭키는 송수신자가 동일한 암호화 키를 사용하는 경우로 대칭키 암호화라고 부르며 DES (Data Encryption Standard), 3DES, AES(Advanced Encryption Standard), SEED, ARIA, IDEA(International Data Encryption Standard), RC5(Ron's Code), Skipjack, Serpent, Twofish 등 알고리즘을 사용한다.
=>송수신자가 모두 같은 키를 가지게 되므로 공유키(shared key) 개념이 있다.
=>송신자는 자신이 사용했던 키와 암호문을 함께 수신자에게 전송해야 하는 위험이 있다.
iloveyou => data
3 => key
algorithm =>각 철자를 3자리씩 전/후로 바꾼다.
i(f), l(i), .... =>iloveyou.<=>filsbvlr. (-+3)
공유키(shared key)(대칭키 암호화)는 대칭키(단일키)에 속하는 공유키 암호화로써 개인적인 파일을 암호화할 때 사용하면 좋다. 보통 단일키로 암호화와 복호화를 수행한다.
gpg -c ~ 로 생성하고 gpg ~ 로 푼다. 서로 같은 키를 사용해서 대칭키 기법이라고 부른다.
비 대칭키
비 대칭키는 송수신자가 서로 다른 암호화 키를 사용하는 경우로 비 대칭키 암호화라고 부른다. 비 대칭키를 암호화 할 때 사용되는 알고리즘이 DSA와 RSA(Rivest, Sharmir, Adleman)이다.
=>여기에는 개인키(private key)와 공개키(public key) 개념이 들어있다.
4 => data
송신자는 2, 수신자는 3 => key
알고리즘 => 송수신자는 수신한 데이터에 자신의 키를 제곱한다.
송신자: 4^2 =>16을 보낸다.
수신자: 4^3 =>64를 보낸다.
다시 송신자가 64^2 =>4096
수신자는 16^3=4096이 된다. 여기서 각각 2와 3이 개인키이고, 4096이 공개키이다.
=>여기서의 문제점은 수신자가 자신의 개인키와 공개키를 생성한 뒤 공개키를 송신자에게 보내야 하는데 보안 상 문제 때문에 보통은 웹에 두고 송신자가 다운받아서 사용하게 한다. 은행 등에서 수 많은 사용자에게 일일이 공개키를 보낼 수 없기 때문에 은행에는 각 개인이 만든 공개키를 웹에 저장해두고 개인은 개인키만 가지고 있다가 인터넷 뱅킹 등에서 자신의 개인키와 은행에 접속해서 공개키를 얻어서 작업하게 한다.
공개키(public key)/개인키(private key) : 비대칭키 암호화
비 대칭키인 개인키/공개키 암호화는 공적인 비밀 파일을 주고받을 때 사용하면 좋다. A와 B의 개인키는 서로 다르지만 공개키는 같아야 한다. A가 B에게 파일을 보낼 때
∎ A는 상대방 B가 보내준 공개키와 A 자신의 개인키로 암호화해서 B에게 보내면
∎ B는 A가 보내온 암호문을 B 자신의 개인키와 A에게 보냈었던 공개키로 복호화한다.
따라서 수신자 B는 송신자 A가 암호화할 때 사용할 자신의 공개키와 A가 보내온 암호문을 복호화할 때 사용될 자신의 개인키를 모두 가지고 있어야 한다. B는 자신이 공개키를 만들 수 있지만 자신의 공개키를 A, C, D, E, ...등 여러 사용자에게 파일로 일일이 첨부해서 보내면 보안상 위험하고 힘든 일이므로 은행과 같은 곳에서는 자신의 공개키를 보안이 잘 되어 있는 웹이나 혹은 신뢰할 수 있는 인증기관(CA)에 공개키를 저장해 두고 C, D, E, ..사용자들이 이 공개키를 다운받아서 사용하게 한다. 공개키와 개인키는 함께 만들어진다.
=>생성은 gpg -c ~ 로 해주고, 풀 때에는 gpg ~로 푼다. 개인키와 공개키는 서로 다른 키를 사용하므로 비 대칭키 기법이다.
A가 B에게 비대칭키 기법으로 암호문을 보낸다면
1) B가 개인키와 공개키를 생성하고
2) B가 A에게 자신의 B 공개키를 보내고
3) A가 B에게서 온 B의 공개키와 평문장을 gpg -c ~ 로 암호화해서 B에게 암호문을 보내고
4) B는 A에게서 온 암호문과 자신의 개인키로 gpg ~ 로 복호화해서 평문장을 만든다.
암호화(encryption)는 데이터 은닉을 위해서 사용한다.
해시(hash)는 데이터의 무결성 보장을 위해서 사용한다.
==>해시는 아주 드믄 경우 A와 B의 원본 데이터가 달라도 두 해시문이 같을 수도 있다.
해시는 절대로 역으로 진행되지 못한다. 해시된 문장과 그 해시된 문장의 원본을 비교해서 해시를 푼다고 한다.
해시 알고리즘은 MD2, MD5, SHA1, SHA256, SHA1024, Blowfish, RIPMED, Whirpool 등이 있다.
=>이 해시는 해시를 풀어주는 웹 사이트나 John the ripper, Cain&Abel, 그리고 hashcrack과 같은 도구를 사용하면 풀 수 있다.
gpgdir
이 도구로 디렉터리를 암호화할 수도 있다.
암호화(Encryption)는 데이터를 다른 사용자가 읽지 못하는 포맷으로 변경하는 것이고, 복호화(Decryption)은 암호화된 데이터를 다시 읽을 수 있는 포맷으로 변경하는 것이다. 파일, 디렉터리, 하드디스크 등을 암호화해두면 데이터를 해킹 당해도 해커는 복호키(decryptor)가 없으면 해독할 수 없어서 데이터가 안전하다는 이점이 있다. HDD나 USB를 암호화해두면 들어있는 모든 디렉터리와 파일들이 한꺼번에 암호화된다.
Windows Server에서는 TPM(Trusted Platform Module) 칩 세트를 이용한 BitLocker로 저장장치를 암호화를 시키는데 파일/폴더 암호화인 EFS보다 더 강력한 기법이다.
Linux에서는 일부 소프트웨어 적인 방법을 사용하는데 gpgdir 도구가 대표적이다. 이 도구로 재귀적으로 디렉터리 암호화와 복호화를 수행해 보자. gpgdir -encrypt ~로 암호화하고, gpgdir -decrypt ~로 복호화한다.
어느 파일을 다운받은 뒤 GPG Sig 서명파일도 다운 받는데
패키지 배포자는 자신의 패키지가 integrity(무결성)한 것을 보증하기 위해서
패키지에 해시키나 ~.asc(전자서명 공개키)를 두고 해당 패키지를 사용하는 사용자들이 손상되지 않은 원본을 사용하고 있다는 것을 확인시켜준다.
파일 시스템(디스크) 암호화하기
앞에서 디렉터리를 암호화해주는 gpgdir이라는 도구를 사용해 보았지만 데이터를 저장하는 하드디스크를 암호화 해두면 해커의 침투를 받거나 디스크를 분실했을 때, 혹은 외부에서 중요한 데이터가 저장된 드라이브를 감출 때 저장된 데이터의 유출을 막을 수 있다. 여기서 소개하는 기법들은 Windows 서버에서 하드 드라이브 전체를 암호화하는 BitLockers나 파일/폴더를 암호화해두는 EFS(Encrypting File System)와 유사한 기법이다. Linux에서는 이런 작업을 HDD나 USB 같은 블록장치들의 마운트를 통해서 조절한다.
Luks(Linux Unified Key Setup)로 HDD/USB 등의 마운트 제한하기
LUKS는 RedHat 계열에서 HDD 전체를 암호화해서 함부로 마운트할 수 없게 해주는 도구이다. 이와 유사한 Linux 오픈소스로는 EncFS가 있고, 파일단위가 아니라 블록단위로 암호화해주는 TrueCrypt도 있다.
파일시스템 전체를 암호화 해두면 파일마다 일일이 암호화해두는 것에 비해서 하나의 패스워드만 있으면 되므로 관리하기가 쉽다. CentOS를 설치할 때 '시스템 암호화'에 체크하거나 Luks를 설치하면 파일시스템을 암호화하기 때문에 마운트하기 전에 암호 문구를 묻게 된다.
TrueCrypt로 HDD/USB 등의 특정 디렉터리 감춰두기
이 도구도 Luks처럼 마운트로 조절한다. 중요한 파일/폴더가 들어 있는 디스크를 암호화된 볼륨으로 만들어 두고, 필요하면 어디에나 마운트 시켜서 사용한 뒤, 다시 umount 해서 감추는 기능이다. 역시 암호문구가 필요하다.
SSH 서버에서 패스워드가 아닌 공개키로 인증 받기
현재까지 SSH 연결에서 클라이언트가 서버에 접속할 때 사용자_명과 패스워드를 인증 받았었는데 이것을 개인키/공개키 구조로 바꿔서 패스워드 없이 키로 인증 받고 연결되게 할 수 있다. 보안 상 SSH로 연결했을 때 Telnet 보다 보안이 좋다는 것은 중간에 패스워드가 노출되었어도 암호문으로 되어 있어서 풀 수 없다는 점 때문이다. 하지만 연결 자체를 인증키로 해주면 패스워드를 알고 있어도 인증키가 없으면 연결이 불가하므로 한층 더 보안이 강화된 연결이 된다.
SSH 서버를 이용할 각 SSH 클라이언트들은
① 이 자신의 개인키와 공개키를 생성해서
② 공개키는 서버의 공개키 키링에 저장해두고 자신은 개인키만 가지고 있다가
③ SSH 서버에 로그인할 때 로컬의 개인키와 서버에 저장된 자신의 공개키로 인증받아서 연결되게 된다.
일반적으로 Public Key 관리는 보통 두 가지로 하는데
1) 각 사용자(클라이언트)가 Public-Private Key(pair)를 생성해서 public-key를 서버에 저장시키고, 클라이언트가 private-key로 서버의 인증을 받아서 들어가거나
2) 또는 서버가 Private-Public Key(pair)를 생성해서 Public-key는 서버가 가지고 있고, Private-key를 각 클라이언트에게 배포해서 들어오게 한다.
서버에 공개키가 있는 클라이언트들만 SSH 서버에 로그인할 수 있으므로 보안이 무척 좋아지게 된다. 서버에 있는 프로그램, 문서, 그리고 DNS 서버 등에 공개키를 적용해두면 개인키가 있는 클라이언트들만 해당 프로그램, 문서, DNS 서버 등을 이용할 수 있게 된다.
=>이렇게 하면 서버에 공개키가 있는 클라이언트들만 SSH 서버에 로그인할 수 있으므로 보안이 무척 좋아지게 된다. 서버에 있는 프로그램, 문서, 그리고 DNS 서버 등에 공개키를 적용해두면 개인키가 있는 클라이언트들만 해당 프로그램, 문서, DNS 서버 등을 이용할 수 있게 된다.