320x100
320x100

개요

이게뭐약 프로젝트에서는 식약처에서 제공하는 오픈 데이터베이스를 사용한다

그런데 프로젝트의 구조가 바뀌면서 데이터베이스를 암호화해서 파일로 만들고 이를 읽어서 복호화하는 과정이 필요하게 되었다

 

 

 

 

RSA 암호화 시도

공개키-비밀키 구조로 강력한 보안을 제공하는 RSA 암호화를 사용하려고 했었다

그러나 `error:0409A06E:rsa routines data too large for key size` 오류가 발생하는 것이었다

알고보니 RSA 암호화는 암호화 키 보다 큰 크기의 데이터를 암호화 할 수 없었다

 

https://2mukee.tistory.com/948

 

nodeJS RSA 암호화 및 복호화하기 (대용량 데이터까지)

import { publicEncrypt, publicDecrypt } from "crypto";function encryptData(data) { const publicKey = fs.readFileSync(path.join(__dirname, `../rsa/id_rsa.pub`)); const buffer = Buffer.from(JSON.stringify(data)); return publicEncrypt({ key: publicKey }, buff

2mukee.tistory.com

 

 

 

 

 

AES 암호화 시도

그리하여 데이터 크기에 상관없이 암호화를 할 수 있는 AES 암호화로 방향을 틀었다

구현까지는 오래걸리지 않았으나, 이상하게 JSON 데이터를 복호화 해보면 항상 끝에 있는 글자가 소실되었다

암호화에서 문제인지도 알 수 없는 노릇이라 이러저리 해매고 있었는데,

우연히 나온 오류를 해결하는 과정에서 정답을 찾을 수 있었다

 

https://stackoverflow.com/questions/62813904/node-js-decipher-final-throws-wrong-final-block-length-error

 

Node JS decipher.final() throws "wrong final block length" error

I am trying to encrypt/decrypt. Encryption works fine and it writes encrypted data to file. While decrypting I am getting an error of length issue. I have used "utf-8" format but error

stackoverflow.com

 

이 글에 나온대로 암호화를 할 때 아래와 같이 했더니 모든 데이터가 정상적으로 암호화 및 복호화 되었다

- 암호화

1. 데이터를 JSON.stringify 후 버퍼로 만든 다음 inputEncoding을 utf8로 설정

2. writeFileSync 할 때 암호화된 string을 hex로 변환 후에 utf8 포맷으로 저장

  private encryptData(resourceData: Object) {
    const { aesKey, aesIv } = secret;

    const cipher = crypto.createCipheriv(
      "aes-256-cbc",
      Buffer.from(aesKey, "hex"),
      Buffer.from(aesIv, "hex")
    );

    return Buffer.concat([
      cipher.update(Buffer.from(JSON.stringify(resourceData), "utf8")),
      cipher.final(),
    ]);
  }
  
const jsonDatas = [{ ... }]; // 데이터 생략
const encryptedData = this.encryptData(jsonDatas);
fs.writeFileSync(resultFileName, encryptedData.toString("hex"), "utf8");

 

- 복호화

1. 암호화된 파일을 utf8로 읽어온다

2. 읽어온 데이터를 hex Buffer로 만든 다음 복호화

  private decryptData(encryptedResourceData: string) {
    const { aesKey, aesIv } = secret;

    const decipher = crypto.createDecipheriv(
      "aes-256-cbc",
      Buffer.from(aesKey, "hex"),
      Buffer.from(aesIv, "hex")
    );

    return Buffer.concat([
      decipher.update(Buffer.from(encryptedResourceData, "hex")),
      decipher.final(),
    ]);
  }
  
const filePath = '...' // 생략
const encryptedResourceData = fs.readFileSync(filaPath, "utf8");
const decryptedResourceData = this.decryptData(encryptedResourceData);

// json 파일로 뽑아서 확인
fs.writeFileSync(resultFileName, decryptedResourceData);
300x250
728x90