crypto-js to node:crypto

crypto-js를 이용해서 암호화를 작성해놓은 코드가 있었는데, 작성시기가 2~3년 전쯤이었다.

어느날 그냥 crypto-js를 찾아봤는데 더이상 서스테이닝을 안한다고 한다. 후… 그럼 버려야지. 그런데 문제가 있다. 이거 그냥 CryptoJS.AES.encrypt 이런 식으로 사용했었는데 이게 몇비트고 어떤 방식으로 동작하는지 자세히 알아야하는데 코드를 보니 너—-무 구닥다리 자바스크립트라서 코드 따라가는 것 조차 버거웠다..

그냥 다른걸 쓰자니 이미 이걸로 암호화되서 저장된 값들이 있어서 이걸 복호화하는걸 만들어야하니 결국에는 삽질을 해야한다는 결론에 도달했다.

그래서 이리저리 막 해보는데 안되는거임 ㅠㅠ 근데 crypto-js 깃헙 들어가보니까 누가 올려 놨더라… 2달 좀 안됐네…

https://github.com/brix/crypto-js/issues/468#issuecomment-1783351942

저 이슈에는 decrypt밖에 없긴 하지만 encrypt는 그걸 거꾸로 하면 되므로 둘다 만들었고 잘 작동한다.

const crypto = require("node:crypto");

function encodeText(text) {
  return new TextEncoder().encode(text);
}

function getSeasoning(key, salt) {
  const password = Buffer.concat([Buffer.from(key, "utf8"), salt]);
  const md5Hashes = [];
  let digest = password;
  for (let i = 0; i < 3; i++) {
    md5Hashes[i] = crypto.createHash("md5").update(digest).digest();
    digest = Buffer.concat([md5Hashes[i], password]);
  }
  return {
    key: Buffer.concat([md5Hashes[0], md5Hashes[1]]),
    iv: md5Hashes[2],
  }
}

function decrypt (text, passphrase) {
  const buffer = new Uint8Array(Buffer.from(text, "base64"));
  const salt = buffer.slice(8, 16);
  const { key, iv } = getSeasoning(passphrase, salt);
  const contents = buffer.slice(16);
  const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);

  return Buffer.concat([
    decipher.update(contents),
    decipher.final(),
  ]).toString("utf8");
}

function encrypt (text, passphrase) {
  const salt = crypto.randomBytes(8);
  const { key, iv } = getSeasoning(passphrase, salt);
  const contents = encodeText(text);
  const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
  return Buffer.concat([
    encodeText("Salted__"),
    salt,
    cipher.update(contents),
    cipher.final(),
  ]).toString("base64");
}

근데 문제는 싹 다 갈아엎으면서 노드를 안쓰고 디노를 쓸거라서 여기서 다시 삽질을 해야한다! 야호 신난다!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다