Node.js를 이용한 단방향 암호화 알고리즘 제작

Node.js를 이용한 단방향 암호화 알고리즘의 제작 과정

Node.js를 이용한 단방향 암호화 알고리즘 제작
출처: 링크

본 글은 고등학교 수학 교과 세부 특기사항 기재를 위해 제작한 자료를 바탕으로 작성하였습니다.


고등학교 수학 교과의 세부 특기사항 작성을 위한 자료 조사 중 이산수학 이라는 분야를 알게 되었다. 이산수학이란

실수처럼 연속성이 있는 것들이 아니라 주로 정수, 논리 연산같이 서로의 값들이 연속적이지 않고 뚝뚝 떨어져 있거나 구분되어 '셀 수 있는' 것들을 주로 연구하는 학문.

을 의미한다. 이산수학에는 2015년 개정 고등학교 교육과정 수학에 있는 경우의 수(합의 법칙, 곱의 법칙)부터 시작하여 순열, 조합, 급수, 유한수열 등을 취급하는데, 암호 알고리즘과 코드, 암호 분야도 취급한다. 이 중에서 필자는 암호 알고리즘(또는 암호화 알고리즘. 이하 “암호화 알고리즘”이라 통칭함)에 관심이 생겨 더욱 깊이 조사하기 시작했다. 조사해보니 암호화 알고리즘에는 여러 종류가 있었는데, 대표적으로 양방향 암호화 알고리즘(이하 “양방향 암호화”)과 단방향 암호화 알고리즘(이하 “단방향 암호화”)으로 나눌 수 있다. (그림 1-1 참고)

[그림 1-1. 암호화 알고리즘의 종류 분류도]

단순히 말하자면 단방향 암호화는 평문의 암호화는 가능하나 복호화가 불가능한 암호화 알고리즘, 양방향 암호화는 암/복호화 모두 가능한 암호화 알고리즘이라 정의할 수 있다.

단방향 암호화는 암호화된 암호문을 받는 자가 복호화를 할 수 없다는 특징이 있으며, 주로 회원가입 기능을 제공하는 서비스에서 회원들의 비밀번호를 관리할 때 주로 사용한다. 만약 해커가 데이터베이스를 탈취한다 해도, 해커가 받는 비밀번호의 내용은 단방향 암호화 알고리즘으로 암호화되어있어 회원의 진짜 암호는 알지 못하게 되기 때문이다. 단방향 암호화의 종류로는 크게 SHA-n(SHA-1, SHA-256 등)과 MD5가 있다. (아래 표-1 참고)

[표-1. 단방향 암호화의 종류]

반면에 양방향 암호화는 암호화뿐만 아니라 복호화 또한 가능하다. 양방향 암호화 알고리즘은 크게 대칭키 암호화와 비대칭키 암호화로 나뉜다. 대칭키 암호화는 암호화할 때 사용하는 Key와 복호화에 사용하는 Key가 같은 경우, 비대칭키 암호화는 암/복호화할 때 사용하는 Key가 다른 경우이다. 자물쇠를 예로 든다면 대칭키 암호화는 자물쇠를 잠글 때와 풀 때 모두 같은 키를 사용하는 경우이고 비대칭키 암호화는 자물쇠를 잠그는 키와 푸는 키가 다른 경우라고 할 수 있다. 대칭키 암호화에는 AES128, AES256 등이 있고, 비대칭키 암호화에는 DSA(전자서명), RSA 등이 있다. (아래 표-2 참고)

[표-2. 양방향 암호화의 종류]

암호화 알고리즘을 처음 배우는 입장에서, 단방향 암호화가 만들기 더 용이할 것 같아 단방향 암호화를 사용해 직접 암호화 알고리즘을 만들었다.


암호화 알고리즘은 Node.JS를 이용하여 제작하였다. 제작 과정을 모식도로 나타내면 다음과 같다. (그림 3-1 참고)

[그림 3-1. 알고리즘 제작 과정 모식도]

암호화 방법은 단방향 암호화로 채택하였고, 암호화 공식은 간단한 일대일함수로 작성하였다.

$f(x) = x + 1$ (단, $x∈ℤ$)

특정 문자열(평문)을 Buffer 처리, toJSON() 함수를 이용해 데이터값을 가져와 위 암호화 공식에 대입한 후 문자열 단위로 합치고 btoa() 함수를 이용해 Base64로 인코딩된 ASCII로 변환하는 방식으로 암호화 구조를 작성한다. 이 암호화 공식을 이용하여 암호화 구조를 조직하였을 때, 코드를 다음과 같이 작성할 수 있다. (아래 참고, 동작 원리는 후술)

(async () => {
  var PlainText = "Hello World!"
  var BufferedPlainText = Buffer.from(PlainText) //"Hello World!"를 Buffer화 한 것.
  var ChipertextArray = []
  var BPTJson = BufferedPlainText.toJSON()

  await BPTJson.data.forEach(x => {
    ChipertextArray.push(x + 1)
  }) // 암호화 공식
  var ChiperText = ChipertextArray.join('') // 문자열 단위로 합침.
  console.log(`평문: ${PlainText}`)
  console.log(`암호문: ${btoa(ChiperText)}`)
})()

암호화 공식을 이용한 단방향 암호화 알고리즘 코드

평문인 “Hello World!”를 직접 만든 암호화 알고리즘에 대입하였을 때, 다음과 같은 암호문을 얻을 수 있다. (그림 3-3 참고)

[그림 3-3. 평문 “Hello World!”를 암호화한 결과]

영어뿐만 아니라 한국어도 가능하며, UTF-8로 나타낼 수 있는 모든 문자열은 알고리즘에 대입할 수 있다.


“Hello World!”라는 평문을 Buffer화 하였을 때, 평문의 단어는 분리되어 Buffer화 된다. 그리고 그 값은 다음과 같다.

<Buffer 48 65 6c 6c 6f 20 57 6f 72 6c 64 21>

원래 Buffer는 2진수로 저장하기 때문에 0과 1로 표현되어야 하지만 Node.JS의 경우 16진 수로 저장하기 때문에 살짝 다르게 보인다. 이를 toJSON() 함수를 이용해 객체화시키면 다음 과 같다.

{
 type: 'Buffer',
 data: [
 72, 101, 108, 108, 111,
 32, 87, 111, 114, 108,
 100, 33
 ]
}

여기에서 data만 추출하여 다음과 같은 배열을 얻는다.

[
 72, 101, 108, 108, 111,
 32, 87, 111, 114, 108,
 100, 33
]

이 배열 속 각각의 정수들을 forEach 문으로 돌려 각각 암호화 공식에 대입한다. 대입 후 나오는 배열은 다음과 같다.

[
 73, 102, 109, 109, 112,
 33, 88, 112, 115, 109,
 101, 34
]

이 배열 속 정수들을 문자열로 가정하고, 서로 이어붙인다.

73102109109112338811211510910134

이를 btoa() 함수에 넣어 Base64로 인코딩하면 “Hello World!”의 암호문을 얻을 수 있다.


이번 수학 교과 세부 특기사항을 위해 이 활동을 해보며 컴퓨터 공학이 수학과 밀접히 관련되어 있고 암호 알고리즘에 대해서도 자세히 공부하게 된 계기가 되었다. 이렇게 보니 우리 일상에서 수학이란 보이는 곳과 보이지 않는 곳 모두 어디에나 존재하고 중요한 역할을 한다는 것을 깨달았다. 평소에는 수학을 왜 배우는지 몰랐는데 이젠 조금이나마 이해할 수 있게 된 거 같다. 결론적으로 이번 활동을 통해 암호화 알고리즘에 관련해서도 관심을 가지게 되었고, 진로 설정에 참고할 수 있을 것 같다.

이번에 만든 암호화 알고리즘을 제작만으로 그치지 않고 나름대로 연구, 실험해보며 다음과 같은 결론을 얻을 수 있었다.

첫째, 알고리즘의 암호화 방법이 너무 단순하다는 것을 확인하였다. 암호화에 사용한 $f(x) = x + 1$ 함수는 너무 단순해서 알고리즘의 내부 구조만 파악한다면 충분히 적은 시간 안에 복호화가 가능할 것이라는 결론을 얻을 수 있었다.

둘째, 평문이 다름에도 암호문이 겹칠 가능성이 존재한다는 것을 확인했다. 아직 완벽히 검증해보진 못했지만 이보다 훨씬 복잡한 구조의 SHA-1의 경우 같은 해시 값을 가질 수 있다고 입증되었다. 이는 SHA-1 연산을 922경 3372조 368억 5475만 번 이상 진행하여 충돌을 규명하였는데, 이러한 연산을 컴퓨터로 수행하려면 약 6000년 정도가 소요된다. 그렇기에 검증은 할 수 없지만 구조가 단순하기 때문에 충분히 두 개의 다른 평문의 암호문이 겹칠 가능성이 있다는 결론을 얻을 수 있었다.

차후에 이 두 문제에 대한 구체적인 해결 방안에 관한 연구가 필요해 보인다.

참고 문헌

본 문서는 다음 논문 또는 자료를 참고하여 작성하였습니다.

김지완, "SEED를 이용한 암호화 알고리즘의 분석 및 개선." 국내석사학위논문 청주대학교 대학원, 2008. 충청북도

OpenJS Foundation, 『Node.js v8.17.0 Documentation』, Node.js, https://nodejs.org/dist/latest-v8.x/docs/api/buffer.html#buffer_buffer

ayoung0073, 『[Security] 비밀번호 단방향 암호화』, ayo.log, https://velog.io/@ayoung0073/Security-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98 %B8-%EB%8B%A8%EB%B0%A9%ED%96%A5-%EC%95%94%ED%98%B8%ED%99%94, 2021. 6. 30.

inyong_pang, 『[Programming] 암호화 알고리즘 종류와 분류』, inyong_pang.log, https://velog.io/@inyong_pang/Programming-%EC%95%94%ED%98%B8%ED%99%94-% EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A2%85%EB%A5%98%EC%99%8 0-%EB%B6%84%EB%A5%98, 2021. 3. 31.

모든 사진, 동영상, 논문을 포함한 저작물의 저작권은 해당 저작자에게 귀속됩니다.

© 2022-2023 Sanghyuk Park. All Rights Reserved.