최근 몇 년 사이에 브라우저 혹은 OS에서 제공하는 비밀번호 관리 시스템을 이용하는 사람이 많아졌다. 혹은 1Password와 같은 애플리케이션을 이용하는 사람도 적지 않다.
이런 제품을 사용한다면 한 번쯤 정말 안전한 게 맞을까?
라는 의심을 해본 적이 있을 것이다. 이번 글에서는 금고 시스템이라고도 부르는 비밀번호 관리 시스템이 안전한 이유를 알아보고 금고 시스템을 직접 구현해 볼 것이다.
암호화에 대한 정의
이 글에 관심을 가진 개발자라면 대부분 암호화가 무엇인지 대략 알고 있을 것이다. 당연하지만 암호라는 것은 오래전부터 사용되어 왔고 많은 시행착오와 발전을 거쳐 개발 세계에 도입된 것이다. 그러니 먼저 암호화의 정의에 대해 알아보자.
암호학은 방해 행위로부터 프로토콜을 방어하는 것을 목표로 하는 과학이다. (...)
당신은 몇 시간 정도 마법검을 내려놓고 낮잠을 좀 자고 싶다. 이를 위한 프로토콜을 한 가지 구성해보면 다음과 같다.
- 땅에 무기를 내려 놓는다.
- 나무 아래서 낮잠을 잔다.
- 땅에서 무기를 들어 올린다.
물론 이는 좋은 프로 토콜이 아니다. 낮잠을 자는 사이 누군가가 마법검을 훔칠 수 있기 때문이다. 여기서 암호학의 역할을 마법검을 훔쳐가려는 적의 존재를 고려하는 것이다.
- 리얼월드 암호학 1장 4쪽
위와 같이 비우호적인 존재로부터 프로토콜을 방어하는 것이 암호학의 목표라고 할 수 있다. 조금 더 단순하게 표현하자면 타인이 알 수 없도록 평문(Plain text)를 암호문(Cipher text)으로 바꿔서 전달하는 것을 의미한다.
간단한 사례를 살펴보면 원시적인 암호화 방법으로 카이사르 암호(시저 암호)라는 것이 있다. 카이사르 암호는 치환 암호의 일종으로 암호화하고자 하는 내용을 알파벳별로 일정한 거리만큼 밀어서 다른 알파벳으로 치환하는 방식이다. 예를 들어 3글자씩 밀어내는 카이사르 암호로 'COME TO ROME'을 암호화하면 'FRPH WR URPH'가 된다. 이렇게 암호화된 문장을 다시 복호화하려면 암호화할 때와 같은 거리만큼 밀어내면 된다. 여기서 프로토콜은 문장을 다른 사람에게 전달하는 것이고 3글자씩 밀어낸다는 것이 암호화의 핵심이다. 물론 이런 방식은 매우 취약하기에 현대에선 사용되지 않는다.
![](/images/2024-04-14-encrypted-vault-system/caesar-cipher.png)
만약 스포츠를 좋아한다면 실시간으로 전략을 정할 때 사인을 보낸다는 것을 알고 있을 것이다. 이때 전략이 유출되면 안 되기 때문에 팀 내에서 수신 호의 의미를 정하고 외부에 공개하지 않는다. 그렇지만 상대편 또한 의미를 해석하려 하기에 키 사인(Key sign)을 사용하여 숨기기도 한다. 이 또한 암호화의 한 형태라고 할 수 있다.
![](/images/2024-04-14-encrypted-vault-system/sport-sign.jpeg)
이런 단순한 형태의 암호화를 거쳐 오늘날의 암호화는 복잡하고 검증된 알고리즘을 사용한다. 이런 알고리즘을 이용하면 비밀번호 관리 시스템을 만드는 것도 가능하다. 이 글에서는 프로토콜을 어떻게 안전하게 만들 것인가?를 다루는 것이 목적이며 알고리즘이 어떻게 이루어지는지는 다루지 않을 것이다. 따라서 복잡한 수학적인 지식은 필요하지 않다.
케르크호프스의 원칙
공개된 암호화 표준을 구축하는 것은 케르크호프스의 원칙이라는 개념과 관련이 있다. 이 원칙은 대략 다음과 같다 '우리가 가장 많이 사용하는 알고리즘을 적이 발견하지 못하리라고 기대하는 것은 어리석은 일이다. 차라리 적에게 공개적으로 개방하자'
- 리얼월드 암호학 1장 9쪽
카이사르 암호나 스포츠에서 사용되는 사인과 다르게 프로그래밍에 쓰이는 암호화 관련 알고리즘은 대부분 공개되어 있다. 앞서 소개한 사례는 알고리즘이 유출되는 경우 너무나도 쉽게 복호화가 가능하다. 그러니 알고리즘이 공개되었는데 정말 안전한가?라는 의문이 충분히 들 수 있다. 결론부터 말하자면 최소한 요즘 프로그래밍에 사용되는 알고리즘은 안전하다고 말할 수 있다.
케르크호프스 혹은 커코프라 불리는 원칙은 Auguste Kerckhoffs가 작성한 글인 군사용 암호 설계 원칙을 살펴보자. 한국어 위키백과에 실린 내용은 다음과 같다.
- 암호체계는 수학적으로는 해독불가능하지 않다고 하더라도, 실질적으로 그래야한다.
- 암호체계는 비밀에 부쳐질 필요가 없어야만 하며, 적의 손에 떨어지더라도 문제가 없어야 한다.
- 키는 글로 쓰여지지 않더라도 교환 혹은 보관할 수 있어야 한다. 당사자들의 의지에 의해서 바뀌거나 수정될 수 있어야 한다.
- 전신에 적용할 수 있어야 한다.
- 이동이 가능해야하며, 암호 체계의 사용과 기능을 위해 여러 사람의 협력을 필요로 하지 않아야 한다.
- 마지막으로, 시스템의 활용을 요구하는 여러 상황들이 주어졌을 때, 암호 체계는 이용이 쉬워야 하며, 정신적인 압박감이나 여러 규칙들의 관찰을 필요로 하지 않아야 한다.
이 중 두 번째 암호체계는 비밀에 부쳐질 필요가 없어야만 하며, 적의 손에 떨어지더라도 문제가 없어야 한다
가 케르크호프스의 원칙으로 알려졌으며 소프트웨어적으로 표현한다면 암호화 알고리즘이 노출되더라도 안전해야 한다고 할 수 있다. 이 말처럼 이미 HTTPS나 이 글에서 다루는 비밀번호 관리 시스템 등 많은 영역에서 AES, RSA 등 공개된 암호화 알고리즘을 사용하지만 충분히 안전하다.
알고리즘이 공개되어도 안전할 수 있는 이유는 비밀 키에 있다. 현대에서 사용되는 대부분의 알고리즘은 비밀 키를 다른 사람이 모른다면 알고리즘이 알려지더라도 암호문을 안전하게 전달할 수 있다. 즉, 비밀 키를 통해 알고리즘이 아닌 프로토콜을 안전하게 만드는 것이다. 그러니 오히려 알고리즘을 공개하여 더 많은 사람들이 검증하고 개선할 수 있도록 하는 것이 더 안전하다고 할 수 있다. 우리가 사용하는 암호화 알고리즘은 많은 사람들이 허점을 찾는 것에 도전했으며 그 많은 도전을 이겨내고 남은 것이다.
고전 암호는 왜 위험한가?
말은 쉽지만 공개되어도 안전한 알고리즘을 만드는 것은 쉬운 일이 아니다. 오늘날의 컴퓨터는 사람이 절대 따라갈 수 없는 엄청난 연산량을 가지고 있다. 반면 컴퓨터가 등장하기 전 고전 암호라 불리는 암호 체계는 이러한 연산량을 고려하여 탄생하지 않았다.
예를 들어 앞서 사용했던 카이사르 암호는 특정한 숫자를 비밀 키로 사용하여 알파벳을 밀어내지만 비밀 키를 모르더라도 해독하는 것이 어렵지 않다. 알파벳은 겨우 26개이기 때문에 모든 경우의 수를 다 해보면 쉽게 해독할 수 있고 컴퓨터는 26개 정도는 순식간에 처리할 수 있다.
그러면 조금 더 복잡한 고전 암호는 어떨까? 16세기에 지오반 바티스타 벨라소라는 이탈리아인이 만든 비즈네르 암호가 있다.1 원리는 카이사르 암호와 비슷하지만 키와 알고리즘이 조금 더 복잡하다. 만약 키가 DUF
고 HI THERE
이라는 문장을 암호화한다면 KU VJZUJ
가 된다.
![](/images/2024-04-14-encrypted-vault-system/vigenere-cipher.png)