Hello, Android!

crypto 모듈 본문

Node

crypto 모듈

lwndnjs93 2021. 1. 26. 23:06

crypto 모듈에는 여러가지 암호화 메서드가 있으며 몇몇은 실제 서비스에도 사용이 가능하다

실제 서비스를 하는 경우 고객의 개인정보는 반드시 암호화를 하여 관리해야만 한다

 

현대에 많이 사용하는 암호화 시스템으로는 크게 단방향 암호화 시스템, 양방향 암호화 시스템이 있다

단방향 암호화 시스템은 암호화 하고자 하는 데이터 평문을 암호문으로 만드는것은 얼마든지 가능하지만

그 반대인 암호문을 다시 평문으로 만드는 복호화 하는것은 매우 어렵다

일반적으로는 사용자들의 비밀번호를 암호화 하여 저장하는 용도로 많이 사용한다

예를들어 사용자가 abcd1234 라는 비밀번호를 사용한다면 

평문을 암호화 하여 저장을 하여도, 이후에 사용자가 abcd1234를 입력할때

DB에 저장된 암호문과 동일한 값이 나와 로그인이 가능하다

하지만 암호문을 다시 평문으로 복호화 하는것은 매우 어렵다

다만 몇몇 알고리즘은 컴퓨터의 발전으로 안전하지 않은 알고리즘도 있다

 

양방향 암호화 시스템은 평문을 암호화 하는것도, 암호문을 평문으로 복호화 하는것도 가능하다

복호화가 가능한 이유는 바로 키를 이용하여 평문을 암호화 하기때문에 

암호화에 사용한 키를 알고있으면 복호화가 가능하다

 

- 단방향 암호화

단방향 암호화 알고리즘 중에서 SHA512 알고리즘으로 "Hello, Ryan!!" "Hello, Muzi!!" 두 문장을 암호화 했다

crypto 모듈에 createHash(), update(), digest() 세 함수를 활용한다

createHash() 함수는 암호화에 사용할 알고리즘을 넣는다 여기서는 SHA512를 활용한다

update() 함수는 암호화를 할 문자열 평문을 넣는다

digest() 함수는 인코딩 방식을 넣어준다 base64 hex latin1이 있지만 base64가 문자열이 짧아 자주 사용된다

실행 결과 첫번째 두번째 로그에는 같은 평문을 같은 알고리즘으로 암호화 했지만

인코딩 방식이 다르기때문에 다른 값이 나왔다

같은 암호화 에서도 base64 방식이 16진수 보다 길이가 짧은것을 볼수있다

세번째 로그에서는 같은 알고리즘, 인코딩 방식을 사용하지만

평문이 다르기 때문에 암호문도 서로 다른것을 볼수 있다

 

아주 드물게 서로 다른 평문이지만 같은 암호문이 나오는 경우가 있다

이런 경우 충돌이 발생했다고 한다

충돌하는 값이 많이 발견되어 더이상 사용하지 않는 알고리즘이 있는데 md5와 SHA1 알고리즘이다

 

현재 주로 사용하는 알고리즘들 중에 노드에서 지원하는 pbkdf2 라는 알고리즘이 있다

이 알고리즘은 기존 문자열에 특정 문자열을 붙인 뒤 암호 알고리즘을 반복하여 적용하는 것이다

pbkdf2에서 평문에 추가로 붙게되는 문자열을 salt라고 하는데 randomBytes 함수를 사용하여

64바이트 크기의 랜덤한 문자열을 만들었다

pbkdf2 함수에서는 매개변수로 평문, salt, 반복횟수, 출력값의 크기, 알고리즘을 넣는다

위의 경우 "Hello, Ryan!!"이라는 평문을 랜덤하게 만든 64바이트의 문자열을 붙여서

sha512알고리즘으로 10만번 암호화 하여 64바이트의 암호문을 만들어낸다

노드에서 사용 가능한 단방향 알고리즘들을 알고싶으면

crypto.getHashes() 함수를 사용하면 지원하는 알고리즘들을 볼수있다 

 

- 양방향 암호화

양방향 암호화는 crypto.createCipheriv() 함수를 사용한다

매개변수로 첫번째는 암호화 알고리즘 두번째는 암호화에 사용할 키 세번째는 초기화 벡터를 넣어준다

이번에 사용한 AES256의 경우 키는 32바이트 초기화 벡터는 16바이트의 크기를 가진다

cipher.update()에서는 매개변수로 평문, 평문의 인코딩 방식, 암호문의 인코딩 방식을 넣어준다

cipher.final()에서는 암호문의 인코딩 방식을 넣어주면 된다

crypto.createDecipheriv()는 복호화에 사용되며 알고리즘, 키, 초기화 벡터를 넣는다

실행 결과 base64의 짧은 암호문과 복호화 한 뒤의 평문이 그대로 나온것을 볼수있다

 

양방향 암호화 알고리즘에서 암호문을 평문으로 복호화 할때는

암호화에 사용한것과 동일한 키를 필요로 한다고 했다

하지만 위에서는 키 이외에 초기화 벡터 iv를 추가적으로 사용했다

초기화 벡터가 어떤것인지 간단하게 찾아본 결과

첫번째 블록을 암호화 할때 사용되는 값이라고 한다

내 생각에는 pbkdf2에서 salt를 평문에 붙여 암호화 하는것과 유사한것이라 생각한다

다만 첫번째 블록에만 붙여서 사용한다

운용 방식마다 초기화 벡터를 사용하는 방법이 다르며, 벡터에 요구되는 성질도 다기도 하지만

같은 초기화 벡터가 사용되서는 안된다는것은 어디서든 동일하다

이는 초기화 벡터가 같은 경우 비슷한 평문을 암호화 하는 경우

앞부분 블록이 같게 되는 보안 문제가 발생하기 때문이다

 

첫번째 블록을 암호화 할때 초기화 벡터를 사용하기 때문에

복호화 과정에서도 암호화에 사용한것과 동일한 키와 초기화 벡터가 필요하다

 

'Node' 카테고리의 다른 글

자식 프로세스  (0) 2021.01.30
thread  (0) 2021.01.30
exports와 require  (0) 2021.01.26
node의 내장 객체(global, console, timer)  (0) 2021.01.24
node의 모듈  (0) 2021.01.23