본문 바로가기

개발 일기/NodeJS

[Node] 메일 인증 암호화 #crypto #encoding

Node.js의 최근 Documentation

이전에 쓴 양방향 암호화 코드를 사용하려고 봤더니 오류가 나서 확인해본 결과 기존에 쓰던

 

createCipher()와 createDecipher()가 곧 사라질 거라는 소식이 들렸다.

 

그래서 이번에 새로운 createCipheriv()와 createDecipheriv() 썼는데 아직 잘 모르겠다. 정리하면서 공부해 보자.

 

매개변수로 사용되는 값들

알고리즘에는 여러 가지가 있는데 공홈에서는 aes192와 aes-128-ccm정도가 쓰여있었다.

다른 사이트를 찾다가 본 알고리즘이 aes-256-cbc여서 이걸로 해보기로 했다.

256이어서 그런지 key도 256bit가 필요하다. 아니면 오류남... 32글자의 암호키가 필요하다.

여기서는 항상 같은 키로 복호화도 필요하기 때문에 고정값을 사용했다.

 

iv는 처음 보는 녀석이었다. 그래서 찾아보니 initialization vector라는 초기화 벡터라는 것이었다.

초기화 벡터는 첫 블록을 암호화할 때 사용되는 값을 의미한다. 운용 방식마다 초기화 벡터를 사용하는 방법이 다르며 초기화 벡터에서 요구되는 성질도 조금씩 다를 수 있지만, 같은 초기화 벡터가 반복되어 사용되어서는 안 된다는 성질을 공통적으로 가진다. -위키백과-

 

처음에 한번 쓰이고 안 쓰는 키 같은 느낌이다.

 

이렇게 이전에 쓰던 함수와 결합하여 암호화 함수를 만들었다.

 

- 암호화 함수

export const cipher = char => {
  const cipher = crypto.createCipheriv(
    "aes-256-cbc",
    Buffer.from(key), //256bit(32char)
    vi //16char
  );
  const result = cipher.update(char, "utf8", "base64") + cipher.final("base64");
  return result;
};

 

- 복호화 함수

export const decipher = char => {
  const decipher = crypto.createDecipheriv(
    "aes-256-cbc",
    Buffer.from(key),
    vi //16char
  );
  const result =
    decipher.update(char, "base64", "utf8") + decipher.final("utf8");
  return result;
};

 

이렇게 암호화하여 메일 인증 링크에 넣고 링크를 클릭하면 암호화된 값을 가져온 뒤 복호화하여 해당 이메일의 주소를 알아낼 수 있다.

 

여기서 또 문제가 발생했다.

 

특수문자 인코딩 오류

 

이메일에 링크를 보낼 때 링크에 암호화된 값이 들어가기 때문에 특수문자들이 잔뜩 들어갔다. 여기서 문제가 "+"가 들어가니 띄어쓰기로 인식해서 링크에서 get으로 값을 받을 경우 문제가 생겼다.

 

그래서 링크에 붙일 때 node의 기본 기능인 encodeURIComponent()를 사용해 인코딩해서 주소에 넣어줬다.

그리고 get으로 받을 때 decodeURIComponent()으로 디코딩을 해주니까 모두 해결되었다. 2시간은 고생한 듯...ㅠ_ㅠ

 

이렇게 해서 메일 인증이 가능해졌다~~!!