Frontend/React

[React] crypto-js 양방향 암호화

Sungwoo Koo 2023. 9. 1. 10:58

목차

  1. crypto-js
  2. crypto-js 설치
  3. crypto-js 사용 예시

 

crypto-js

crypto-js는 해쉬 함수를 통해 양방향으로 암호화 할 수 있도록 해주는 Node.js 기반 패키지이다.

 

crypto-js 설치

npm i crypto-js

 

 

crypto-js 사용 예시

내 경우, React 앱 내 src/util/ 경로에 EncryptService.js 파일을 생성해 활용했다.

나는 AES 암호화 방식을 선택했으며, 여기를 참고해 원하는 암호화 방식을 사용해도 상관없다.

// EncryptService.js
import CryptoJS from "crypto-js";
import { secrets } from "../../secret";

const encryptionKey = secrets.key;

export const encryptData = (plaintext) => {
  const ciphertext = CryptoJS.AES.encrypt(plaintext, encryptionKey).toString();
  return ciphertext;
};

export const decryptData = (ciphertext) => {
  const bytes = CryptoJS.AES.decrypt(ciphertext, encryptionKey);
  const decryptedPlaintext = bytes.toString(CryptoJS.enc.Utf8);
  return decryptedPlaintext;
};

 

CryptoJS.AES.encrypt(), CryptoJS.AES.decrypt()를 사용하기 위해서는 비밀 키를 지정해야 한다.

내 경우, src/ 경로에 secret.js 파일을 생성해 EncryptService.js에서 불러와 사용했다.

secret.js 는 .gitignore에 등록해 노출되지 않도록 했다.

 

// secret.js
export const secrets = {
  key: "secret key",
};

 

이제, 암호화/복호화를 사용할 페이지에서 EncryptService를 불러와 사용해보자.

 

먼저, EncryptService에서 만든 encryptData, decryptData 함수를 import 한다.

import { encryptData, decryptData } from "./util/EncryptService";

 

[암호화]

Person을 생성하는 handleSaveCreate 함수에서 Email을 암호화해서 서버에 전송하는데에 encryptData를 사용한다.

const handleSaveCreate = async () => {
    try {
      const newPersonData = {
        email: encryptData(editEmail), // 암호화
        name: editName,
        team: Number(editTeamIdx),
        position: Number(editPositionIdx),
      };

      const response = await axios.post(
        "http://localhost:3003/api/test/person",
        newPersonData
      );

      const newPerson = {
        ...newPersonData,
      };
      const newPersonResponse = [newPerson, ...personResponse];
      setPersonResponse(newPersonResponse);
      dispatch(setPersonList(newPersonResponse));

      setCreatingPerson(false);
      setEditIndex(null);
      setEditEmail("");
      setEditName("");
      setEditTeamIdx("");
      setEditPositionIdx("");
    } catch (error) {
      console.error("Error creating data:", error);
    }
  };

 

[복호화]

API 요청을 통해 암호화한 Email을 서버로부터 전달 받았을 때,  Email을 복호화해서 화면에 보여준다.

이 때, decryptData를 사용한다.

{personResponse.map((item, index) => (
            <tr key={item.email}>
              <td>{index + 1}</td>
              <td>{decryptData(item.email)}</td>
              <td>item.name</td>
            </tr>
))}

 

[주의사항]

암호화 한 값을 API 요청에 활용해야 하는 경우가 있다.

예) 암호화한 email을 Path에 활용하는 경우 

 await axios.delete(
          "http://localhost:3003/api/test/person/" + email
        );

암호화 된 Email에 '/'와 같은 Path에 들어가게 되는 경우, 의도와 다르게 동작하게 된다.

 

따라서, 이런 경우에는 다음과 같이 encodeURIComponent를 활용해 처리한다.

 await axios.delete(
          "http://localhost:3003/api/test/person/" + encodeURIComponent(email)
        );