[React] 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)
);