Record

이스터에그 (인프라 프로젝트3 / git ssh 연결, public key, private key) 본문

프로젝트

이스터에그 (인프라 프로젝트3 / git ssh 연결, public key, private key)

now-record 2025. 11. 12. 18:09
반응형

저번에 git hub ssh연결까지 했다. 

그런데 git에서 ssh연결을 하려면 public key와 private key라는 개념이 나와서 잡고 가고자 한다. 

 

"공개키는 은행의 계좌번호와 유사하고 개인키는 비밀번호 pin과 유사하다"

 

이렇게 개념을 잡고 가면 될꺼 같다. 

 

그전에 대칭키와 비대칭키에 대한 개념을 이해하고 가야한다. 

 

1. 대칭키 암호 (Symmetric Key)

특징: “하나의 같은 키를 함께 쓰는 방식”

  • 암호화할 때 쓰는 키 = 복호화할 때 쓰는 키
    • 내가 1234라는 비밀번호로 파일을 암호화하면
    • 상대도 1234를 알아야 그 파일을 열 수 있음

장점                                                                          

  • 빠르다.
    대량의 데이터(파일 전송, 스트리밍 등)에 적합
  • 구현이 단순

단점

  • 키를 어떻게 서로 안전하게 공유하냐가 문제
    → “야 비밀번호 카톡으로 보내줄게” 이러면 이미 위험함

 

대칭키 암호에서는 하나의 비밀키 K를 송신자와 수신자가 공유하고, 그 같은 K 값으로 암호화도 하고 복호화도 한다

 

2. 비대칭키 암호 (Asymmetric / Public Key)

특징: “서로 다른 두 개의 키를 쓰는 방식”

  • 공개키 (public key)
    • 누구에게나 줘도 되는 키
    • “이걸로 나에게 보낼 데이터를 잠가주세요”
  • 개인키 (private key)
    • 나만 알고 있어야 하는 키
    • “잠긴 걸 열 수 있는 진짜 열쇠”

둘은 수학적으로 연결되어 있어서

  • 공개키로 암호화 → 개인키로만 복호화 가능
  • 반대로 개인키로 서명 → 공개키로 검증 가능

장점

  • 상대에게 비밀키를 직접 전달할 필요가 없음
    • 공개키만 인터넷에 올려두면, 누구나 나에게 “비밀 메시지”를 보낼 수 있고
    • 그걸 열 수 있는 건 개인키를 가진 나뿐
  • **인증(서명)**도 할 수 있음
    → “내가 진짜 이 개인키를 가진 사람이다”를 증명

단점

  • 연산이 느리다.
    → 대용량 데이터 전체를 비대칭키로 암호화하는 건 비효율적

 

정리하자면 

각자 자기만의 (공개키, 개인키) 한 쌍을 가지고 있고,서로의 “공개키”를 교환해서, 보낼 때는 항상 “받는 사람의 공개키”로 암호화한다.


근데 문득 그러한 궁금증이 생긴다. 왜 github도 그렇고 공개키가 아닌 비대칭키 암호화 방식을 통해서 ssh연결을 지원할까? 

 

1. 키 전달 문제(Key Distribution Problem) 해결

 

  • 인터넷은 기본적으로 도청 가능한 채널
  • “우리만 아는 비밀번호 K”를 만들고 싶은데
    • 전화, 메신저, 메일로 보내면 도청당할 수도 있음
    • 직접 만나서 USB로 주는 것도 현실에선 번거롭고 비현실적

-> 비대칭키는 공개키만 뿌리고 개인키만 가지고 있어도 가능 

 

2. 전자서명 해결

    • A와 B가 같은 키 K를 공유하고 있으면  K를 아는 사람이 보내는 메시지는
    • “A가 보냈다”라고도 할 수 있고 “B가 보냈다”라고도 할 수 있음
      누가 보냈는지 구분이 안 됨

반면

  •  
  • A가 자기 개인키로 서명한 메시지를 보내면
  • 누구든 A의 공개키로 그 서명을 검증할 수 있고
  • “이건 A 개인키 없이는 못 만든 거다”라고 확신 가능

3. 규모(스케일) 문제

 

대칭키만 쓸 때

사용자 N명이 서로 비밀 통신을 하고 싶으면?

  • 사람 쌍마다 키 하나씩 필요
    → 필요 키 개수: N(N-1)/2
  • 100명만 있어도 키가 4,950개
  • 각 쌍마다 키를 만들어서 안전하게 공유해야 함

비대칭키를 쓸 때

  • 사람마다 자기 키쌍 1개만 관리하면 됨
  • 나랑 통신하고 싶은 사람은 내 공개키만 알면 됨
  • 공개키는 막 뿌려도 되고, 누가 어떻게 가져가든 상관 없음

깃에서는 ssh를 암호화 하는 이유는 

1. 통신을 암호화 하기 위해 

2. 중간에 내가 보낼때 다른 서버가 탈취할 수 있기 때문에 

 

그리고 공부를 하다보니 내가 다른 서버와 연결할때쓰는 .pem 파일이 이런 public key와 private key를 담고 있는 파일인걸 알게 되었다.


또 비대칭키로 연결하지 않고 대칭키와 섞어쓴다. 

왜? 라고 하면 이제 비대칭키의 경우 연산이 오래걸려서,무거워서 이다.

 

왜 무거울까?.

그 이유는  대칭키는 같은 키로 되돌릴 수 있는 간단한 비트/바이트 연산(XOR, 치환 등)을 반복하는 구조라 빠르고,

비대칭키는 공개키로는 써도 되지만, 거기서 개인키를 역산하기 아주 어렵게’ 만들기 위해 큰 정수나 타원곡선 위에서 복잡한 수학 연산을 사용하기 때문이다. 

 

그러면 흐름은 대체로 이렇다. 

1. 서로의 public key와 private key로 서로를 인증한다. 

2. 이후 서로를 인증했고 매번 비대칭키로 전송하면 오버헤드가 생기기 때문에, 이번 세션에만 쓸 수 있는 대칭키인 세션키를 생성한다.

3. 서로의 전송을 오버헤드가 적은 세션키로 암호화하고 복호화해서 전송한다. 


 

그렇다면 서로를 어떻게 인증할까? 

나는 서버가 내 공개키로 암호화해서 보내고, 내가 개인키로 복호화해서 다시 보내면 → 서버가 ‘개인키 가진 사람밖에 못 푼다 라는 식으로 생각을 했다, 이건 공개키 암호화를 이용한 챌린지–리스폰스 인증이라고 한다. 

 

반면 ssh접속에서는 위의 인증이 아닌 

실제 SSH 구현 = 유사한 챌린지–리스폰스지만, “서명/검증” 버전으로 구현한다고 한다. 

 

서명 검증 방식은

1. 클라이언트가 서버에 접속하고 서버에 나 이런 public key를 가진 사람이다 라고 보낸다. 

2. 서버는 db에서 이런 public key가 있는지 확인하고, 클라이언트에게 어떤 난수를 보낸다. 

3. 클라이언트는 private key와 어떠한 조합과정을 거쳐서 이 난수와 private key값이 섞인 것을 보낸다. 

4. 서버는 public key로 이 값은 private key값을 가지고 있는 사람만이 만들 수 있단것을 확인하고 인증한다. 

 

이게 가능한건 디지털 서명은 공개키와 개인키가 수학적으로 딱 맞물리게 만들어져 있어서,
오직 그 개인키로만 만들 수 있는 특이한 숫자(Signature)를 만들 수 있고, 서버는 공개키로 그 숫자가 진짜 그런지(=개인키로 만들었을 수밖에 없는지) 검사하는 구조다.

그렇다면 왜  아까 내가 생각한 챌린지-리스폰스 방식이 아닌  서명/검증의 방식을 고수할까?

1. 역할 정리가 깔끔함 (암호화 vs 서명)

  • 암호화(Encryption):
    → “내용을 숨기는 용도” (기밀성, confidentiality)
  • 서명(Signature):
    → “누가 보냈는지, 중간에 안 바뀌었는지 확인하는 용도”
    (신원 + 무결성, authenticity + integrity)

2. 요즘 흔한 키 알고리즘은 ‘서명 전용’인 것도 많음

Ed25519, ECDSA 같은 “서명 전용” 알고리즘
→ 아예 “암호화” 기능이 없고,
→ Sign/Verify만 있음

 

3. 안전하게 설계하기가 쉬움

RSA 는

  • “개인키로 암호화 / 공개키로 복호화”
  • “공개키로 암호화 / 개인키로 복호화”
    이론상 둘 다 “가능해 보이는” 구조라,
    사람들이 예전에 막 섞어서 쓰다가 공격당한 사례가 잔뜩 있음.

그래서 현대 암호학에서는

  • “요건 이 용도로만 써라”가 강하게 정해져 있음
    • RSA-암호화 (OAEP 등)
    • RSA-서명 (PSS 등)
    • ECDSA/Ed25519 → 아예 “서명 전용 알고리즘”

 

 

-> 그림으로 좀 풀어서 넣어야겠다 좀 중구난방하게 정리했네