본문 바로가기
개발/React

리액트 - crypto-js로 문자열 암호화/복호화하기 (Encrypting/Decrypting String)

by 피로물든딸기 2024. 2. 28.
반응형

리액트 전체 링크

 

아래 결과는 링크에서 확인할 수 있다.

 

AES (Advanced Encryption Standard)

- 대칭키 암호화 알고리즘으로, 동일한 키를 사용하여 데이터를 암호화하고 복호화한다.


SHA256 (Secure Hash Algorithm 256-bit)

- 단방향 해시 알고리즘으로, 임의의 데이터를 고정된 길이의 해시 값으로 변환한다.

- 한 번 해싱된 데이터는 원본 데이터로 복원할 수 없다.


crypto-js

 

crypto-js를 이용하면 위에서 설명한 AESSHA256을 간단히 사용할 수 있다.

 

먼저 AES를 사용하기 위해 적절히 키를 만들자.

const SECRET_KEY = "YOUR_SECRET_KEY";

 

사용 예시는 다음과 같다.

import CryptoJS from "crypto-js";

...

let encrypted = CryptoJS.AES.encrypt(text, SECRET_KEY).toString();
let decrypted = CryptoJS.AES.decrypt(encrypted, SECRET_KEY).toString(CryptoJS.enc.Utf8);

 

SHA256는 키가 필요없으므로, 아래와 같이 사용하면 된다.

let hashed = CryptoJS.SHA256(text).toString();

 

Material UITextField와 버튼을 추가해 실제로 문자열을 변경(암호화 / 복호화 / 해싱)해 보자.

 

전체 코드는 다음과 같다.

import React, { useState } from "react";
import { Box, TextField, Button } from "@mui/material";
import CryptoJS from "crypto-js";

const SECRET_KEY = "YOUR_SECRET_KEY";

const EncryptionComponent = () => {
  const [inputText1, setInputText1] = useState("");
  const [inputText2, setInputText2] = useState("");

  const [encryptedAESText, setEncryptedAESText] = useState("");
  const [decryptedAESText, setDecryptedAESText] = useState("");
  const [hashedText, setHashedText] = useState('');

  const encryptAES = () => {
    let encrypted = CryptoJS.AES.encrypt(inputText1, SECRET_KEY).toString();
    setEncryptedAESText(encrypted);
  };

  const decryptAES = () => {
    let decrypted = CryptoJS.AES.decrypt(inputText1, SECRET_KEY).toString(CryptoJS.enc.Utf8);
    setDecryptedAESText(decrypted);
  };

  const hashText = () => {
    let hashed = CryptoJS.SHA256(inputText2).toString();
    setHashedText(hashed);
  };

  return (
    <div>
      <Box sx={{ m: 2 }}>
        <TextField
          label="Text for AES"
          value={inputText1}
          onChange={(e) => setInputText1(e.target.value)}
        />
        <Button
          sx={{ m: 1 }}
          variant="outlined"
          color="warning"
          onClick={encryptAES}
        >
          Encrypt
        </Button>
        <Button variant="outlined" color="success" onClick={decryptAES}>
          Decrypt
        </Button>
        <div>
          <p>Encrypted Text AES: {encryptedAESText}</p>
          <p>Decrypted Text AES: {decryptedAESText}</p>
        </div>
      </Box>

      <hr />

      <Box sx={{ m: 2 }}>
        <TextField
          label="Text for SHA256"
          value={inputText2}
          onChange={(e) => setInputText2(e.target.value)}
        />
        <Button
          sx={{ m: 1 }}
          variant="outlined"
          color="warning"
          onClick={hashText}
        >
          Hash
        </Button>
        <div>
          <p>Hashed Text SHA256 : {hashedText}</p>
        </div>
      </Box>
    </div>
  );
};

export default EncryptionComponent;

참고 - Node JS에는 crypto 모듈이 내장되어 있다.

const crypto = require("crypto");

// 대칭키 생성
const SECRET_KEY = crypto.randomBytes(32); // 256 bits

// 초기화 벡터 생성 (IV)
const iv = crypto.randomBytes(16); // 128 bits

// 암호화 함수
const encrypt = (text) => {
  const cipher = crypto.createCipheriv("aes-256-cbc", Buffer.from(SECRET_KEY), iv);
  let encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return { iv: iv.toString("hex"), encryptedData: encrypted.toString("hex") };
}

// 해독 함수
const decrypt = (iv, encryptedText) => {
  const decipher = crypto.createDecipheriv(
    "aes-256-cbc",
    Buffer.from(SECRET_KEY),
    Buffer.from(iv, "hex")
  );
  let decrypted = decipher.update(Buffer.from(encryptedText, "hex"));
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
}

const originalString = "Hello, world!";
const encryptedData = encrypt(originalString);

console.log("Encrypted:", encryptedData);

const decryptedString = decrypt(encryptedData.iv, encryptedData.encryptedData);

console.log("Decrypted:", decryptedString);

반응형

댓글