SSH 클라이언트 사용법
$ ssh username@hostname -p port command_line
여기서 username@ 과 -p port, command_line은 생략 가능!
username을 명시하지 않을 시, windows/macOS/Linux 클라이언트의 username이 적용된다.
-p는 포트번호를 지정하는 옵션으로, 지정하지 않을 시 기본으로 22번이 할당된다. (well-known port number)
command_line을 명시하지 않으면 쉘을 사용할 것임을 암시하게 된다.
# 예시
ssh admin@abcde.net -p 10022 touch /tmp/i_am_alive
위 명령어는 abcde.net에 존재하는 admin 계정으로 로그인한 것이다.
TCP port 10022를 listening 하는 sshd 프로세스로 접속을 시도함 (서버 운영자가 변경된 port 번호를 유저들에게 사전 공지해야 한다)
명시된 명령줄 touch /tmp/i_am_alive 가 서버 단에서 실행되고 곧바로 클라이언트가 종료된다.
SSH (Secure Shell)의 주요 특징?
- 모든 통신 내용이 암호화되어, 계정, 비밀번호 등 정보의 비밀성을 보장할 수 있음
- 통신 내용의 무결성 보장 : 암호문에 단 1 비트라도 손상되거나 데이터 추가/누락이 발생하면 평문으로 복호화 불가
- 호스트의 진위성 (authenticity)을 확인할 수 있음
원격지 서버 Authenticity 점검 과정?
(base) ➜ ~ ssh srv-adm-sec.net
The authenticity of host 'srv-adm-sec.net (59.6.51.163)' can't be established.
ED25519 key fingerprint is SHA256:Wy0/Pxy+o6pXlLkUaoNJ6PMrO/jhd/Lph48j8jrVoxc.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
# no를 입력할 경우
Are you sure you want to continue connecting (yes/no/[fingerprint])? no
Host key verification failed.
# yes를 입력할 경우
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'srv-adm-sec.net' (ED25519) to the list of known hosts.
클라이언트 단의 유저는 사진 속 지문 SHA256:Wy()~~~Voxc를 보고 해당 서버가 특정 서버 운영자에 의해 개설된 것인지 검증할 수 있다.
이 SSH를 더 잘 이해하기 위해서는, 대칭 암호와 비대칭 암호의 원리 및 활용 방법을 이해함으로써 SSH, HTTPS의 암호화 및 진위성 검증 과정을 이해할 수 있다.
암호의 개념과 원리
- 평문 (plaintext) p :누구나 열람할 수 있는 raw data로, 암호 알고리즘으로 보호해야 할 대상
- 암호문 (ciphertext) c : 비밀을 유지하기 위해 당사자만 알 수 있도록 처리도니 데이터
- 암호화 알고리즘 (encryption algorith) f( . ), 복호화 알고리즘 (decryption algorithm) f ' ( . )
- f = f ' 인 경우도 있음
- 암호 키 k, 복호 키 k '
- 암호화 (encryption) : c <= f(p, k)
- 복호화 (decryption) : p <- f ' (c, k')
- 대칭 암호화
- 암호화, 복호화 단계에서 같은 키가 사용된다. (k = k') 이때 k를 대칭키라고 함!
- 비대칭 암호화 (or 공개키 암호화)
- 암호화, 복호화 단계에서 각각 다른 키가 사용됨
고전 대칭 암호
1. 단일 치환 : 알파벳 한 글자를 정해진 다른 한 글자로 대체하는 방식
ex) 카이사르 암호 : d 알파벳은 항상 a 알파벳으로 치환하는 방식
그러나 이는 k의 경우의 수가 고작 25에 불과하여 취약하다.
2. 다중 치환 : 알파벳 한 글자를 여러 가지 다른 알파벳으로 대체하는 방식
ex) 비제네르 암호
p = "wish to be free from myself" (평문)
k = "secret is beautiful" (암호 키)
p의 첫 글자 'w' => O
p의 두 번째 글자 'i' => M
c = f(p, k) = "OMUY HX JW GVEY YZTG XQWGCJ” "
현대 대칭 암호 : DES, AES
- DES : Data Encryption Standard (블록암호)
- 64bit의 블록 암호화 알고리즘이며, 56비트 크기의 암호화 키로 암호화된다.
- 암호화는 다음 두 가지 기본 변환을 통해 이루어짐
1. 하나의 블록인 64비트를 L1(32비트)과 R1(32비트)으로 나눔
2. R1을 암호화 키로 생성한 S-Box로 f함수를 만들어 치환 작업을 한 후, 이 값을 L1과 XOR한다음 L2와 R2의 위치를 바꿈
- AES : Advanced Encryption Standard
- DES의 암호화 강도가 약해짐에 따라 제시된 암호화 표준으로서, 현재 미국 정부가 채택하여 기밀 문서를 암호화하는데 사용할 정도로 현대에서 많이 사용되고 있는 알고리즘이다.
gpg(GNU privacy guard) 명령을 통해 AES 알고리즘을 직접 실습해보자!
먼저 "It snows today" 평문이 담긴 secrets.txt 파일을 하나 생성해놓았음
$ gpg --output secrets.txt.enc --symmetric --cipher-algo AES256 secrets.txt
위 명령을 해석해보자면, 우선 암호화된 파일의 출력 이름을 secrets.txt.enc로 지정한다.
--symmetric : 대칭 키 암호화를 사용하겠다는 옵션으로, 대칭 암호화에서는 파일을 암호화 및 복호화하는 데 동일한 비밀번호 (passphrase)를 사용한다.
--cipher-algo AES256 : 암호화 알고리즘으로 AES256 을 지정한다.
secrets.txt : 암호화할 원본 파일을 맨 뒤에 기입해주었다.
해당 명령을 실행하면 다음과 같은 화면이 나오게 됨
이는 암호화 시 사용하는 Passphrase를 입력하라는 화면이다.
강력한 패스프레이즈의 원칙은 최소 12자 이상, 숫자, 특수문자, 대소문자 조합 포함하는 문자열을 입력하는 것이다.
근데 한 번 6글자만 입력해봤는데 다음과 같은 화면이 뜨면서 개인이 그냥 통과시킬 수도 있는 것 같음
무튼 비번 입력 후 다음과 같이 다시 한 번 re-enter 해줘야 한다.
명령이 성공적으로 완료되면, 현재 경로에 (암호화 파일).enc 라는 암호화된 파일이 생성된다.
현재는 secrets.txt로 암호화 하였으니 secrets.txt.enc 라는 파일이 생성되었고, 참고로 원본 파일인 secrets.txt는 보안 상 삭제하는 것이 일반적이다!
$ gpg --output secrets.txt --decrypt secrets.txt.enc
이제 암호화된 파일을 복호화하기 위해서 위 명령을 사용한다.
이는 앞서 생성했던 암호화된 secrets.txt.enc 파일을 복호화하여 secrets2.txt(output)로 저장하는 명령이다.
복호화 결과 secrets2.txt가 생성되었고, cat으로 확인해본 결과 암호화 전 원본 파일과 내용이 동일한 것을 볼 수 있다!
2024년 11월 기준, 이 AES 알고리즘은 아직까지 안전하다고 알려져 있고 실제로 많이 사용되고 있다.
그러나 다음과 같은 한계점이 존재한다.
1. 암호문과 암호화 키를 "동시에" 전달해야만 상대방이 평문을 열람할 수 있게 된다.
=> 즉, 비밀번호를 안전하게 전달할 방법이 없음
2. 인터넷이 활성화되며 불특정 유저와의 통신이 잦아지게 된다.
=> 수많은 대칭키를 관리해야 하는 문제가 발생
이런 암호 전달 문제를 연구하기 시작하여 비대칭 암호 개념을 제시한 것이 바로 Diffle-Helman 알고리즘!
Diffle-Helman 키 공유에 관한 기본 아이디어
- 목표 : 자신의 수를 타인에게 알리지 않고 공통된 값을 얻는다.
여기서 공개된 수는 3, 철수의 수는 5, 영희의 수는 7이라고 가정해보자.
철수는 공개된 수 3에 자신의 수 5를 제곱한 3^5 = 243을 영희에게 전달,
영희는 공개된 수 3에 자신의 수 7을 제곱한 3^7 = 2187을 철수에게 전달한다.
그 후 각자 받은 숫자에 대해 자신의 수만큼 다시 제곱해서 상대방에게 넘겨주면 서로 똑같은 값을 갖게 된다!
즉 (3^a)^b 와 (3^b)^a 가 서로 지수 법칙에 따라 같다는 개념을 이용한 것!
이후 통신은 대칭키 암호로 수행하며 상기 비밀 키를 대칭 키로 사용하게 된다.
RSA 알고리즘
- 각 유저가 고유한 N = p*q 값을 가질 때, N을 갖고 p와 q를 유추하기 어렵다. (즉 소인수 분해가 어려움)
- RSA 알고리즘은 정수론 중 소수의 성질을 이용!
- RSA 암호는 250자리이기 때문에 이론상 브루트포스로 찾아낼 수는 있지만, 복호화하는데 우주의 나이만큼 소요된다.
- p와 q라고 하는 두 개의 서로 다른 (p!=q) "소수"를 고른다.
A의 공개키는 이렇게 위 과정으로 구한 두 개의 숫자로 이루어진 <N, e> 이고, 개인키는 <N, d>이다.
A는 <N, e> 만을 B에게 공개하고, B는 이 공개키를 사용하여 자신의 메시지를 암호화하게 된다.
여기서 p와 q의 보안은 매우 중요하다. 이를 갖고 d와 e의 계산이 가능하기 때문!
따라서 공개키와 개인키가 생성이 된 후에는 이 두 숫자를 아예 지워버리는 것이 안전하다.
무튼 핵심은 p와 q를 이용해서 N, e, d를 결정하는 것!
<RSA 알고리즘을 이용한 암호화, 복호화>
공개 키 : (N = 3233, e = 17)
개인 키 : (N = 3233, d = 2753)
예를 들어 평문 m = 65는 다음과 같이 암호화된다.
c = 65^17 (mod 3233) = 2790
암호문 c = 2790은 다음과 같이 복호화된다.
m = 2790^2753 (mod 3233) = 65
참고로 mod 연산이란, a mod b 일 때 숫자 a를 b로 나누었을 때의 나머지를 구하는 연산이다.
즉 10 mod 3이라고 하면 10 % 3 == 1 이므로 10 mod 3 = 1 이다!
비대칭 암호화
공개키(public key) 와 개인 키 (private key) 이렇게 한 쌍의 키로 구성된다.
평문을 개인 키로 암호화 => 암호문 생성 가능 (단, 이 경우 반드시 공개키를 써야만 복호화 가능)
평문을 공개 키로 암호화 => 암호문 생성 가능 (단, 이 경우 반드시 개인키를 써야만 복호화 가능)
기능 1 : 기밀성 확보
Q. 철수가 영희에게 비밀편지를 보내려면?
1. 인터넷에 공개된 영희의 "공개 키"를 찾아 암호화한다.
2. 철수가 만든 암호문은 오직 영희의 "개인 키"로만 복호화된다.
- 평문 m과 hash(m)을 덧붙여 암호화하면 기밀성과 무결성을 동시에 확보할 수 있음!
기능 2 : 전자서명, 부인방지(non-repudiation)
- 부인방지 : 메시지의 송수신이나 교환 후 또는 통신이나 처리가 실행된 후에 그 사실을 사후에 증명함으로써 사실 부인을 방지하는 보안 기술
ex) 인터넷 뱅킹 송금, 공인인증서를 통한 로그인, 온라인 전자상거래
- 철수가 평문 & 평문+해쉬를 철수의 개인키로 암호화한 값을 동시에 전송
- 영희가 철수의 공개키로 복호화한 값과 평문이 일치하면 전자서명 검증 성공
먼저 평문에 대한 해쉬값을 떠놓고 이를 개인키로 암호화하며,
또한 기밀성에 대한 부분이 아니기 때문에 평문을 같이 주는 것임!
위 개념을 이해하면 SSH 프로그램의 동작 과정을 알 수 있다.
SSH internal : SSH 세션 맺기
PS C:\Users\MS> ssh srv-adm-sec.net
The authenticity of host 'srv-adm-sec.net (59.6.51.163)' can't be established.
ED25519 key fingerprint is SHA256:Wy0/Pxy+o6pXlLkUaoNJ6PMrO/jhd/Lph48j8jrVoxc.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
hosts.
SSH 서버와 연결을 시도하면 위와 같은 문구가 콘솔에 뜰 것이다.
위에서 Wy0/Px~~~ 부분이 바로 공개키인데, 이 서버의 공개키는 공개되어도 상관 없기 때문에 클라이언트에게 전달된다.
클라이언트 단의 사용자가 공개키를 '눈으로' 살펴본 뒤 세션을 계속 맺을지 스스로 결정해야 한다.
결정을 내리기 전, 클라이언트 사용자가 서버 운영자에게 연락하여 공개키를 요청해야만 함!
- 원리?
우리 클라이언트에는 이미 알려진 호스트 키 목록들이 있는데, 서버에 접속하면 서버가 제일 먼저 호스트의 공개키를 클라이언트한테 준다.
이렇게 공개키를 주면 클라이언트는 호스트 키의 유효성을 확인(키 목록에 있는지 없는지)한다.
만약 키 목록에 없으면 모르는 서버니까 사용자에게 위 출력과 같은 경고를 보내는 원리이다!
위 출력에서 "yes"를 눌러 세션을 계속 맺을 경우...
Warning: Permanently added 'srv-adm-sec.net' (ED25519) to the list of known hosts.
영구적으로 list of known hosts에 저장이 되었다는 형태로 기록이 된다.
클라이언트(Host PC)에서 list of known hosts를 열람하려면 다음과 같은 명령어를 입력하면 된다.
macOS, Linux : ~/.ssh/known_hosts
Windows: %USERPROFILE%\.ssh\known_hosts
만약 눈으로 서버의 공개키를 검증하고 싶지 않은 경우,
해당 파일에 서버 운영자가 제공한 공개키 데이터를 추가하면 된다!
만약 알고있던 Host 가 자신한테 저장된 공개키가 아닌, 갑자기 다른 공개키를 전달한 경우가 발생하면
다음과 같은 경고 문구가 뜨면서 접속이 차단된다.
PS C:\Users\MS> ssh sa16167@srv-adm-sec.net
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:kWsOnSmF2VTD/N4O/S+OH0ME/2NDbb6agHqD5fVHIGI. # 서버 공개키의 지문 (fingerprint)
Please contact your system administrator.
Add correct host key in C:\\Users\\MS/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in C:\\Users\\MS/.ssh/known_hosts:6
Host key for srv-adm-sec.net has changed and you have requested strict checking.
Host key verification failed.
가능성1 : 적법한 서버 운영자가 리눅스를 포맷하여 새로운 공개키-비밀키 쌍이 생성되었을 수 있음
- 당신이 바로 그 서버 운영자라면, 모든 원격 유저에게 업데이트된 공개 키를 공지할 의무가 존재함
- 모든 원격 유저는 공지 수신 후 known_hosts 파이레서 과거의 서버 공개키를 제거해야 함
가능성2 : 네트워크 세션이 탈취되어 가짜 서버로 접속하게 되었음
- 중간자 공격 (man-in-the-middle attack) 이라고 불리는 공격은, 공격자가 원래 서버와 클라이언트 사이에 위치하여, 가짜 서버를 통해 통신을 중간에서 가로챌 경우 발생할 수 있다.
앞서 진입을 시도했던 서버의 공개키가 변경된 것 같으므로,이를 해결해야 한다.
해결 방법으로는 문제가 발생한 키를 known_hosts 파일에서 삭제하는 것인데, 다음 명령어를 입력하거나 수동으로 ~/.ssh/known_hosts 파일을 열러 해당 호스트와 관련된 라인을 삭제하면 된다.
ssh-keygen -R srv-adm-sec.net
known_hosts 파일을 검토한 뒤 해당 서버의 public key를 찾아서 삭제하고 다시 저장해야만 접속할 수 있게 된다.
이후 해당 서버에 재접속을 시도하고, 공개키 관련 경고에 'yes'로 응답하여 SSH 쉘을 제대로 얻은 것을 볼 수 있다!
참고로 중간자 공격은 클리이언트 (PC)와 서버 사이의 통신을 가로채는 공격 방식이다.
공격자는 중간에 자신이 조작한 서버를 끼워넣고, 클라이언트가 이를 신뢰하도록 속인다.
이를 통해 클라이언트와 서버 간의 데이터를 가로채거나, 클라이언트로부터 전달받은 데이터를 변조할 수 있음!
MITM 공격의 과정
- 공격자는 클라이언트와 서버 사이(예: 공유기, 네트워크 노드 등)에 위치한다.
- 서버를 가장하여 클라이언트에게 가짜 공개키를 제공한다.
- 클라이언트는 공격자의 공개키를 신뢰하게 되고, 이후 통신 내용은 공격자가 복호화할 수 있다.
예시: 공유기와 MITM
- 사용자가 공공 Wi-Fi(공유기)에 연결되어 있고, 해당 공유기가 공격자의 제어하에 있다면, 공격자는 클라이언트와 서버 사이에 끼어들어 데이터를 가로채거나 변조할 수 있다.
'Cryptography' 카테고리의 다른 글
[Crypto] Double DES 문제 풀이 (0) | 2024.08.31 |
---|---|
[Crypto] 고전 암호와 현대 암호 알아보기 (1) | 2024.08.30 |
[Crypto] 메르센 트위스터의 난수 생성 예측하기 (0) | 2024.08.28 |
[Crypto] 암호학 툴 설치하기 (0) | 2024.08.27 |
[Crypto] 난수 생성기 : 메르센 트위스터 (Mersenne Twister) 알아보기 (0) | 2024.08.25 |