본문 바로가기
개발/React

클라이언트단에서 crypto-js 를 이용하여 유저정보 암호화하기

by 안뇽! 2022. 1. 16.
반응형

 

면접을 볼 때 면접관님이 https통신에서도 로그인을 하면 개발자도구의 네트워크 탭에서 유저정보를 평문으로 볼 수 있는데 이것에 대해 생각해본적이 있냐고 물어보셨다. 면접에서는 한번도 생각해본적이 없다고 했었다. 면접관님은 https통신에서는 상관없을것이라고 하셨다.

확인해보니 실제로 네트워크탭에서 암호를 평문으로 확인할 수 있었다.

 

오늘 그때의 면접 질문에 대해 검색을 해보았다.

 

https://okky.kr/article/496801

https://okky.kr/article/496801

딱 내가 원하는 상황이다.

댓글들을 보니깐 '원래 그렇다, 그 감리가 뭘 모르는 사람이다' 등등의 이야기와 함께 '네트워크 탭에 보이는 평문들은 SSL단계로 넘어가기 전의 데이터이다'. 'SSL단계로 넘어가면 암호화가 되기 때문에 상관 없다'는 이야기들이 있었다.

 

다만 몇몇댓글들에서 '감리는 서버로 전달하기 이전단계에서의 암호화를 원하는것같다.' 라는 내용이 있었다.

'클라이언트에서 입력값을 암호화 한 후 서버로 전달' 하는것을 감리가 원한다는 것이었다.

 

댓글들을 더 읽어보니 '어차피 클라이언트에서 암호화를 해봤자 모든 소스가 오픈되어 있기 때문에 역추적이 가능하다' 라는 내용도 있었다.

그런데 key를 env에 넣어두면 역추적이 안되지 않을까?? 싶다.

 

어쨌든 그 댓글과는 별개로 '위 질문에서 감리의 요구사항'을 맞추기 위해  crypto-js라는 라이브러리를 사용해서 클라이언트단에서 암호화를 할 수 있음을 알게 되었다.

 

crypto-js를 구글링을 하며 사용법을 익히고 npx create-react-app 을 통해 간단한 실험을 하였다.

 

App.js코드와 실제 암호화,복호화 값을 공유하자면

import CryptoJS from "crypto-js";
import React, { useEffect, useState } from "react";

function App() {
  // 암호화 할 데이터
  const [id, setId] = useState("");
  const [pw, setPw] = useState("");
  const [hashedData, setHashedData] = useState("");
  const [decryptedData, setDecryptedData] = useState({ id: "", pw: "" });
  const data = {
    id: "ryu9663",
    password: 12345678,
  };
  const secretKey = "1234";
  // 복호화 키 지정

  const privateKey = "secret key";

  const hashFunction = (e) => {
    e.preventDefault();

    // AES알고리즘 사용 암호화
    const data = {
      id,
      pw,
    };
    console.log(data);
    const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), secretKey).toString();

    // AES알고리즘 사용 복호화 ( 복구 키 필요 )

    const bytes = CryptoJS.AES.decrypt(encrypted, secretKey);

    // 인코딩, 문자열로 변환, JSON 변환

    const decrypted = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
    console.log(encrypted);
    console.log(decrypted);
    setHashedData(encrypted);
    setDecryptedData(decrypted);
  };

  return (
    <>
      <form onSubmit={(e) => hashFunction(e)}>
        <div>
          id : <input type="text" value={id} onChange={(e) => setId(e.target.value)} />
        </div>
        <div>
          pw : <input type="password" value={pw} onChange={(e) => setPw(e.target.value)} />
        </div>
        <button type="submit">정보 암호화하기</button>
      </form>
      <div>{hashedData.length > 0 ? hashedData : null}</div>
      <div>{decryptedData.id.length > 0 ? `id는 ${id}이고, pw는 ${pw}입니다.` : null}</div>
    </>
  );
}

export default App;

 

이렇게 암호화 된 값을 axios를 통해 request body로 전달하고, 서버에서 복호화하면 네트워크탭에서 유저정보를 확인할 수 없을것같다.

 

 

반응형