요전에 텔레그램에 대해 썼을 때 이런 저런 질문을 많이 받았다. 바빠서 답변을 많이 못 한 게 에러긴 한데… 여튼 이런 일들을 겪으면서 좀 더 체계적으로 암호학에 대해서 정리해야 겠다는 생각이 싹텄다. 그래서 쓰기 시작했던 글을 여기에 갖다 붙인다. (고로 이것도 날로 먹는 저널이다… 물론 gist에서 꽤 오랫동안 작업하긴 했다.)

암호학을 사용하는 많은 시스템은 세부적으로 무슨 알고리즘을 쓰는지보다는 그 알고리즘들이 어떻게 연결되어 있는지, 즉 구조가 실제 안전성에 더 큰 영향을 미친다. 요는, 알고리즘을 블랙박스처럼 취급해서 알고리즘이 일정한 암호학적 성질을 만족하기만 하면 그걸 연결해서 안전한 구조를 만드는 게 알고리즘 자체보다 더 중요해진다는 얘기이다. 좀 심하게 말하면 아무리 안전한 알고리즘으로 암호화를 해 봤자 키가 옆에 있으면 의미가 별로 없지 않겠느냔 말이다(…). 그래서 이 글은 개별 알고리즘보다는 “암호화”라든가 “키 교환”이라든가 하는 대분류를 설명하고, 각 분류에 속하는 알고리즘은 무슨 조건을 갖춰야 하며 어떻게 써야 하는지를 중점적으로 다룬다.

언제나 그렇듯, 내가 암호학 전문가까지는 아니기 때문에 틀린 점이 있을 수 있으니 주의. (의견은 위의 gist에 댓글을 다는 게 보기 편하다.) 또한 아무리 “고수준”이라는 말을 붙였지만 아무리 써 봐도 초보자를 위한 글은 아니므로… (초보자를 위해서는 대규모의 비유analogy가 필요한 게 사실인데 나는 그만한 창의력이 없다;) 고수준이라는 말은 직접적인 수식과 알고리즘을 최대한 피했다는 의미로 해석해 달라. 마지막으로, 여기에 안 쓰여 있는 중요한 분류들도 많으니 이것만 읽고 암호학은 이제 끝이야! 하는 우를 범하진 않길 바란다. 이를테면 서비스 거부 공격DoS을 버틸 수 있는 암호학적 구조가 있는가? 같은 류의 질문은 여기서 답하지 않는다.

두 사람만이 알 수 있는 새로운 키를 만든다. 이 과정이 끝나도 상대방이 내가 아는 사람인진 알 수 없지만 적어도 상대방과 내가 같은 키를 가지고 있다는 건 확신할 수 있다.

다른 키에서 새로운 키 여러 벌을 만든다. 입력이나 출력이나 암호화 등등에 사용할 수 있어야 하는 키여야 하고, 새로운 키에서 원래 키를 알아낼 방법은 없어야 한다.

어쩌면 엄청 길 수 있는 데이터에서 고정된 길이로 데이터의 요약digest을 끄집어 낸다. 요약만 가지고 데이터에 대한 어떤 정보도 알 수는 없어야 한다(즉, 완전 랜덤한 데이터처럼 보여야 한다). 임의의 두 데이터를 줬을 때 같은 해시가 나오는 가능성이 거의 없어야 한다.

암호 같이 암호화 등에 쓰이기 어려운 입력에서 새로운 키를 만든다. 암호학적 해시의 기본적인 조건과 더불어, 느린 정도를 조정할 수 있어서 무작위 대입을 하는 것도 비싸야 한다.

두 사람이 상대방에 대한 적절한 정보를 가지고 있을 때 한 쪽이 암호화해서 보내면 다른 쪽이 복호화한다. 크게 두 종류가 있다.

두 사람이 같은 키를 가지고 있을 때 한 쪽이 암호화해서 보내면 다른 쪽이 복호화한다. 키가 안 털리면 암호화된 내용을 백날 털어도 아무 정보도 알 수 없어야 한다.

한 사람이 비밀키를 가지고 있고 다른 사람이 그 비밀키에 대한 공개키를 가지고 있을 때 공개키를 가진 쪽이 그걸로 암호화해서 보내면 비밀키를 가진 쪽이 복호화한다. 비밀키에서는 공개키를 쉽게 만들 수 있지만 공개키에서는 죽었다 깨나도 비밀키를 만들 수 없다. 비밀키가 안 털리면 암호화된 내용을 백날 털어도 아무 정보도 알 수 없어야 한다.

한 사람이 비밀키를 가지고 있고 다른 사람이 그 비밀키에 대한 공개키를 가지고 있을 때, 비밀키를 가진 쪽이 메시지와 더불어 비밀키를 가지고 해당 메시지에 짧은 서명을 붙이면 공개키를 가진 쪽이 해당 서명이 정말로 대응되는 비밀키로 서명한 게 맞는지를 확인한다. 비밀키/공개키의 컨셉은 비대칭 암호화와 같음. 바깥에서는 데이터는 변조시킬 수 있지만 올바른 서명은 만들 수 없어야 한다.

두 사람이 같은 키를 가지고 있을 때, 한 쪽이 데이터와 더불어 키를 가지고 해당 데이터에 짧은 메시지 인증 코드MAC를 붙이면 다른 쪽이 키와 데이터와 인증 코드를 가지고 메시지가 안 바뀌었는지 확인한다. 바깥에서는 데이터는 변조시킬 수 있지만 키를 모르는 이상 올바른 인증 코드는 만들 수 없어야 한다.

서로 아는 두 사람만이 알 수 있는 새로운 키를 만든다. 키 교환과 비슷하지만 서로에 대한 정보를 알고 있고 그 정보를 키 교환과 함께 검증하고자 한다는 게 차이점.

두 사람이 같은 키를 가지고 있을 때, 한 쪽이 데이터와 키를 인증된 암호화 알고리즘에 집어 넣어서 보내면 다른 쪽이 같은 키와 암호화된 데이터를 가지고 이게 해당 키로 암호화된 게 맞는지 확인하고 맞으면 복호화된 데이터를 얻는다. 메시지 인증이랑 대칭 암호화를 하나로 합쳤다고 생각하면 쉽다.

적절한 방법으로 예측이 불가능한(랜덤한) 난수를 생성한다.