TIL/개발 칼럼

야크 털은 어디까지 깎아야 할까? JWT, 비대칭키, RSA, 유클리드 호제법, 정수론

김민석(갈레, 페퍼) 2022. 11. 10. 16:39
반응형

안녕하세요🙌! 개발자 갈레입니다!

 

이번 글에서는 야크의 털은 어디까지 깎아야할까(문제를 해결하기 위해 어느정도 깊이까지 공부해봐야할까)에 대한 저의 경험과 결론을 공유하려 합니다.

 

<그림1. 야크의 털 깎기>

야크 털 깎기란 '목표한 일 하나를 하기 위해 연관된 작업들을 하다가 결국 원래의 목적을 잃고 완전히 관련 없는 작업을 하게 되는 것'입니다. 아래는 하나의 예시입니다!

  1. 나무를 베기 위해 도끼를 구했다.
  2. 도끼날이 너무 무뎌 날을 갈기 위한 돌을 구하려 한다.
  3. 그런데 어떤 마을에 정말 좋은 돌이 있다는 이야기를 듣는다.
  4. 그 마을에 가기 위해 야크를 구한다.
  5. 야크 털이 너무 길어서 털을 깎기 시작한다.

 

결론

결론부터 말하겠습니다! 저는 문제를 본래의 목적과 상관 없이 너무 깊이 파고드는 느낌이 들 땐 아래 질문 세가지를 던집니다! 세가지에 대한 답을 바탕하여 STOP or GO를 결정합니다.

  1. 나의 경험적 무의식이 STOP을 말하는가?
  2. 나의 목표한 일을 하는 것과 밀접한 관계가 있나?
  3. 이곳은 연구자의 영역인가? 엔지니어의 영역인가?

 


저의 경험 및 사고 과정

시작 : Custom JWT 라이브러리 구현

저는 로그인 로직의 성능을 개선하기 위해 JWT를 구현했었습니다. JWT 필터를 만들 때 처음엔 우선 돌아가게 만들기 위해 JWT 오픈 소스 라이브러리를 사용했습니다. 이후 오픈 소스 라이브러리는 유지보수에 약하기도 하고 저는 개발자이므로 라이브러리를 직접 구현하기로 결정했습니다. JWT 라이브러리 내 Algorithm 인터페이스를 적용하여 책임을 분리하는 등 로직 구현을 마친 후, JWT 내에서 사용하는 기술에 대해 궁금해졌습니다.

 

<그림2. JWT 구조>

 

아시다 싶이 JWT의 시그니처는 비밀키를 이용한 해싱 혹은 비대칭 키를 이용하여 생성됩니다. 문득 궁금진거죠. '내가 비대칭키를 사용하는 코드를 직접 짠다면 추상화된 레이어 작동 원리인 구체화된 레이어를 알아야 하지 않을까?' 라고 생각했죠. 그렇게 비대칭키의 작동 원리에 대해 알아보기 시작했습니다. 이때 한번 스스로 질문을 던졌었습니다. 너무 깊게 들어가나? 하지만 아래 두 근거로 인해 Keep going 했습니다.

 

  • 근거1: HTTPS가 비대칭키가 아니라 대칭키를 사용하는 이유도 이와 관련된 것을 알았기 때문에 더욱 의미가 있었습니다.
  • 근거2: 대학교에서도 네트워크 보안 강의에서 이를 알려주기 때문에 백엔드 개발자로서 알아야할 필수 지식이라고도 판단했습니다.

 

대칭 키의 작동 원리

 

<그림3. 대칭키 작동 원리> 출처: 네트워크 보안/안동대/차영욱 교수

 

 대칭 키는 순열, XOR, 회전을 이용하여 확산과 혼동의 효과를 높입니다. 이 모든 과정은 단순 비트 연산입니다. 대칭키에 대한 취약성은 키의 길이와 반비례합니다. 브루트포스하게 가능성 있는 키를 모두 맞춰봐야 하는데, 해당 연산은 키의 길이가 길 수록 맞춰봐야할 키가 많아지므로 부하가 커지게 됩니다. DES가 추후 3중 DES 혹은 AES로 대체된 요인도 결국 키의 길이 때문이죠.

 

비대칭 키의 작동 원리

 

<그림4. 비대칭 키 작동 원리> 출처: 네트워크 보안/안동대/차영욱 교수

 

이해한 것

 비대칭 키는 '(원문^공개키) mod 파이(N) = 암호문, (암호문^개인키) mod 파이(N) = 원문' 방식으로 암호화 됩니다. 공개키와 개인키는 엄청나게 큰 수입니다. 원문에 수많은 승수 연산을 하기 때문에 비대칭키 사용은 대칭키에 비해 시간이 오래걸립니다. HTTPS에서 대칭키를 이용하여 통신하는 것이 이러한 연산 부하 때문이죠. 공개키와 개인키의 안정성은 파이(N)에서 공개키와 개인키를 만들 때 사용하는 큰 소수 p,q를 추론하기 어렵다는 일방향적 함수의 성질에 기반합니다. N은 p*q로 만들어지는데 N이 엄청나게 큰 수라면 p,q를 추론하기 어렵다는 것이죠. 큰 수를 소인수 분해한다는 것은 연산 부하가 큽니다!

 

 

야크의 털을 깎고 있나?

<그림5. 야크의 털 깎기>

 문득 RSA의 식인 '(원문^공개키) mod 파이(N) = 암호문, (암호문^개인키) mod 파이(N) = 원문'가 정말로 그렇게 동작하는지 궁금해졌습니다! 또한 공개키 하나에 정말로 개인키가 하나만 존재하나 궁금해졌죠. 이를 알기 위해 RSA를 증명하는 방법을 알아봤습니다. 여기서 부터 문제였습니다. 오일러의 정리, 페르마의 소정리 등이 나왔죠. 해당 이론을 내가 알 필요가 있나? 스스로 질문을 던졌습니다. 컴퓨터 공학과 커리큘럼엔 보통 있지 않았습니다. 정보 통신과에만 종종 '정수론'이라는 강의로 존재했죠. 문득 생각이 들었습니다. '야크의 털을 깎고 있나?'. 야크의 털인지 아닌지 확인하기 위해 주변 개발자 분들의 조언을 구했습니다. 

 

 

주변 조언

 3-5명 정도의 개발자 분들께 조언을 구했습니다. 저의 궁금증과 왜 그러한 과정을 겪게 됐는지 얘기를 했습니다. 많은 분들의 결론이 다 똑같진 않지만 비슷한 문맥의 얘기를 했습니다.

 

Jxxxx님 / 13년차 시니어 개발자님

  • 나의 목표한 일을 하는 것(공개키와 개인키를 어떻게 생성하나?, 암/복호화 방식이 어떻게 되나)과 밀접한 관계가 있나?
  • 엔지니어로서 실질적으로 도움이 되나?

Fxxx님 / n년차 시니어 개발자님

  • 나의 목표는 무엇인가? 그것과 부합하나?

Rooxx님 / 3년차 주니어 개발자님

  • 나의 경험적 무의식이 STOP을 말하는가?

Hxxx님 / n년차 주니어 개발자님

  • 깊이 들어가는 것은 좋다. 하지만 실무에서 쓸 일이 있을까?

 

결론

 다시 결론입니다! 위 주변 조언을 바탕하여 아래와 같은 결론을 냈습니다. 문제를 본래의 목적과 상관 없이 너무 깊이 파고드는 느낌이 들 땐 아래 질문 세가지를 던지기로 했습니다. 세가지에 대한 답을 바탕하여 STOP or GO를 결정하는 거죠. 여러분들도 야크의 털을 깎고 있다는 생각이 들땐 어떻게 하시나요? 어떤 기준으로 STOP or GO를 판단하시나요? 제 글이 여러분들에게 도움이 됐으면 좋겠습니다:)

  1. 나의 경험적 무의식이 STOP을 말하는가?
  2. 나의 목표한 일을 하는 것과 밀접한 관계가 있나?
  3. 이곳은 연구자의 영역인가? 엔지니어의 영역인가?
반응형