brunch

You can make anything
by writing

C.S.Lewis

by 테크유람 Apr 01. 2021

SSH-KEYGEN으로 인증키 생성하는 원리와 방법



SSH(Secure Shell) 프로토콜은 기존 ID/PW 방식을 사용하여 호스트에 접속하는 Telnet, rlogin, rsh 등의 프로토콜 특유의 보안 취약점을 해소하기 위해 사용합니다. 비밀번호 방식은 비밀번호가 저장된 파일이 도난당하거나, 비밀번호 자체가 유출되면 호스트가 노출된 비밀번호를 바꾸지 않는 이상 보안에 취약하기 때문입니다.


SSH 프로토콜은 단순한 평문 전달 방식의 ID/PW가 아닌, 대칭키 암호화 방식 혹은 비대칭키 암호화 방식을 사용합니다. 후자의 경우, 클라이언트와 서버는 공개키(public key)와 비밀키(secret key)를 통해 인증하는 방식이기 때문에 한 쌍(pair)의 SSH 키가 필요합니다.


SSH는 클라이언트 및 서버 인증에 각각 사용됩니다. 아래는 클라이언트 인증에 대한 예제입니다.

<SSH 연결 과정>


SSH 통신은 기본적으로 TCP 포트 22번을 사용하며 클라이언트가 SSH 접속 요청을 서버에 보내면 서버는 그 클라이언트의 공개키로 암호화한 메시지를 클라이언트에게 인증 용도로 내려줍니다. 클라이언트는 한 쌍으로 만들어졌던 비밀키를 이용해 암호화된 메시지를 복호화하며 인증이 완료됩니다. 한 쌍이 아닌 다른 비밀키로는 메시지 복호화를 할 수 없습니다.


페어(pair)라는 표현을 사용하는 이유는 인증에 사용하는 두 개의 키(공개키, 비밀키)는 하나의 쌍으로 만들어지고 사용되기 때문입니다. 실제로 SSH 키 생성을 위해 사용하는 ssh-keygen 명령은 비밀키를 먼저 만들고, 그 값과 passphrase를 활용해 공개키를 만듭니다. 따라서 같은 페어가 아닌 키들은 당연히 동시에 사용될 수 없습니다. SSH 키는 인증에 사용되는 패스워드 역할을 하기 때문에 키 자체가 유출되지 않도록 보관해야 합니다. 보안이 더욱 중요한 서비스에서는 인가되지 않은 접근으로부터 키를 보호하기 위해 KMI(Key Management Infrastructure)를 사용하기도 합니다.


ssh-keygen은 SSH의 대표적 구현체인 OpenSSH 라이브러리에 포함되어 있습니다. 만들어진 키 페어는 시스템 자동 로그인, SSO(Single Sign-On) 또는 서버 호스트 사설 인증 등에 사용할 수 있습니다. ssh-keygen은 아래와 같은 경우 많이 사용합니다.


PuTTy 프로그램에 생성한 SSH 키를 등록하고 SSH 프로토콜로 특정 서버에 접속할 수 있다.

GitHub이나 BitBukcet과 같은 Repository 서비스도 ID/PW 외에 SSH 키 로그인 방식으로 접근한다.

JWT(JSON Web Token)의 서명 알고리즘은 공개키와 비밀키를 이용한 한 쌍의 키를 지원한다.


ssh-keygen을 사용하는 예제를 통해 어떤 알고리즘과 방식으로 한 쌍의 키를 만드는지 보겠습니다.

% ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/brandon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/brandon/.ssh/id_rsa.
Your public key has been saved in /Users/brandon/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:hjbXN0Bbx6t+RWKf/u6fFrupg3gyk3BsXKqKLfHAV1g brandon@mac1
The key's randomart image is:
+---[RSA 2048]----+
|          . ...  |
|       E . o ..  |
|      o   o    . |
|     . o . o  + .|
|  .   = S + oo +.|
|   + o = * ... oo|
|    =   = o.. ..o|
|   .o. . * o...+o|
|   ..o.   =  o+*O|
+----[SHA256]-----+


위 코드를 간략히 설명하자면,

1) ssh-keygen 명령을 별도의 매개 변수 없이 실행하였다.

2) 비밀키가 저장될 위치를 묻는다.

별도의 파일 위치 없이 ENTER를 하면 기본값은 사용자의 /. ssh/id_rsa에 생성된다.

별도의 알고리즘 지정이 없으므로 RSA 알고리즘을 사용하겠다는 의미도 포함되어 있다.

(SSH는 RSA 외에도 DSA, ECDSA, ED25519 등의 알고리즘을 지원합니다)

키 생성 시의 알고리즘은 -t(type) 옵션을 사용하여 알고리즘과 키의 크기(bit)를 지정할 수 있다.

ssh-keygen -t rsa -b 4096
ssh-keygen -t dsa
ssh-keygen -t ecdsa -b 521
ssh-keygen -t ed25519


3) passphrase를 묻는다.

passphrase는 키를 암호화 시에 salt처럼 사용하는 값이다. 비밀키가 노출되는 만약의 사태에 대비한다면, 충실한 passphrase를 사용하는 것이 암호화 강도를 높일 수 있는 방법이다.


4) /.ssh/id_rsa.pub 파일도 생성되었다.

이 파일은 공개키(public key)다. 비밀키(id_rsa)가 먼저 만들어지고 passphrase를 조합하여 public 키가 만들어졌다. 따라서 공개키와 비밀키는 한 쌍(pair)으로 만들어졌고 같이 작동한다는 것이 이제 이해될 것이다.


5) Key Fingerprint 정보는 아래의 조합이다.

SHA256:hjbXN0Bbx6t+RWKf/u6fFrupg3gyk3BsXKqKLfHAV1g brandon@mac1

SHA256 -> Base64 인코딩 된 SHA256 해시 알고리즘을 사용하는 것을 의미한다.

hjbXN0Bbx6t+RWKf/u6fFrupg3gyk3BsXKqKLfHAV1g -> 키의 Fingerprint 정보

brandon@mac1 -> 키의 위치


6) randomart 이미지 -> Fingerprint의 시각화(visualize)

~/.ssh 폴더를 보면, 비밀키와 공개키가 생성되어 있음을 확인할 수 있다.

% ls -al ~/.ssh
total 40
drwx------   7 brandon  600   224 Dec 14 10:32 .
drwxr-xr-x+ 92 brandon  600  2944 Dec 10 12:36 ..
-rw-r--r--   1 root    600   157 Jul 11  2018 config
-rw-------   1 brandon  600  1823 Dec 14 10:32 id_rsa
-rw-r--r--   1 brandon  600   398 Dec 14 10:32 id_rsa.pub
-rw-r--r--   1 brandon  600   558 Nov 12 11:53 known_hosts
-rw-r--r--   1 brandon  600   352 Nov 20  2018 out


이제 두 개의 키의 내용을 각각 확인해보겠습니다. 

% cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEA9MC5YSbfk0iY5ZJQzJoK2E3bhV30i8D2TJMsgIuRd68gm0pRrbEs
H6QWcsN/IyRVgRQr0QJFzoEG6kNjQM4e+PWr413cYruQIqO+t+rMRJziAxB8m088Qu2Ezm
eb5xZBNLFQzESlWufEi3ACWXSbO7ld/WfkstuAA/WjTj8ImmNsw9lKMsEhnuF2Hl6mnCaa
..........
TWks9MqwpAvstduxUeXw5N+lQZyHTiNXzxigqJuv0AFcZd3SUAAACBAPgV/E3K7fBwxeOT
qAXmwgjjWdUFR0iipl3A9i2PFBsfyrQRKUeXEAbkVBpUZZMQlSH/Gk+9RqAOzKftG5ULOt
EnNDkgSq0isD1IX02Neb/w+6aD6vHY4RVPCs8Iw/6AHn4RrIoqEGHewUbE7HbQOEkY+Y8A
IabwMHcOjPG0CPTrAAAAEHNha2FuZ0BzZWwtbXBuYWIBAg==
-----END OPENSSH PRIVATE KEY-----

% cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD0wLlhJt+....+qCjPc1B8GUT3 brandon@mac1


이제 공개키, 비밀키 한 쌍이 생성되었고 사용할 수 있는 준비가 되었습니다.




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari