Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

Node.js crypto.createCipheriv() 메서드 완벽 가이드

crypto.createCipheriv() 메서드는 지정된 알고리즘과 키(key), 초기화 벡터(iv)를 기반으로 암호화 객체(cipher object)를 생성한 후 반환하는 Node.js crypto 모듈의 핵심 함수입니다. 이 메서드를 사용하면 AES 계열 알고리즘 등 다양한 대칭키 암호화를 손쉽게 구현할 수 있습니다.

문법(Syntax)

crypto.createCipheriv(algorithm, key, iv, options)

매개변수(Parameters)

  • algorithm – 암호화에 사용할 알고리즘을 지정합니다. aes-192, aes-256, aes-256-cbc 등이 대표적인 값입니다.

  • key – 알고리즘이 실제로 사용하는 원시 키(raw key)입니다. 문자열(string), Buffer, TypedArray, DataView 타입을 사용할 수 있으며, 필요에 따라 KeyObject 타입도 허용됩니다. 키 길이는 선택한 알고리즘의 요구 사항과 정확히 일치해야 합니다.

  • iv – 초기화 벡터(Initialization Vector)로, 동일한 키로 암호화하더라도 매번 다른 결과가 나오도록 만들어 보안성을 높이는 역할을 합니다. iv 자체는 비밀로 유지할 필요가 없습니다. 문자열, Buffer, TypedArray, DataView 타입을 지원하며, 사용하는 암호화 모드에서 iv가 필요하지 않은 경우 null을 전달할 수 있습니다.

  • options – 스트림 동작을 제어하기 위한 선택적 매개변수입니다. 단, CCM 또는 OCB 모드(예: aes-256-ccm)를 사용할 때는 이 매개변수가 필수입니다.

예제 1: randomBytes로 키 생성 후 데이터 암호화하기

먼저 createCipheriv.js라는 이름의 파일을 생성하고 아래 코드를 복사합니다. 그런 다음 다음 명령어로 코드를 실행할 수 있습니다.

node createCipheriv.js

createCipheriv.js

// crypto 모듈 불러오기
const crypto = require('crypto');

// 알고리즘 설정
const algorithm = 'aes-256-cbc';

// 32바이트 키 생성
const key = crypto.randomBytes(32);

// 16바이트 iv 벡터 생성
const iv = crypto.randomBytes(16);

// 데이터를 암호화하는 함수 정의
function encrypt(text) {
  // 위에서 정의한 매개변수로 cipher 객체 생성
  let cipher = crypto.createCipheriv(
    'aes-256-cbc', Buffer.from(key), iv);

  let encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);

  // iv와 암호화된 데이터를 반환
  return { iv: iv.toString('hex'),
    encryptedData: encrypted.toString('hex') };
}

// 함수 실행 및 결과 출력
var output = encrypt("TutorialsPoint");
console.log(output);

실행 결과

C:\home\node>> node createCipheriv.js
{ iv: '3dd899aa441c00d4d8d2ff95abb2e684',
encryptedData: 'b4985053bc1507fc25a4d99823dc8b03' }

위 예제에서는 crypto.randomBytes()를 사용해 무작위 키와 iv를 생성했습니다. 실행할 때마다 새로운 iv가 생성되므로 같은 평문이라도 매번 다른 암호문이 출력됩니다.

예제 2: scryptSync와 스트림 방식으로 암호화하기

이번에는 비밀번호로부터 scryptSync()를 통해 키를 파생하고, 스트림(stream) 이벤트 방식으로 데이터를 암호화하는 예제를 살펴보겠습니다.

// crypto 모듈 불러오기
const crypto = require('crypto');

// 알고리즘 설정
const algorithm = 'aes-192-cbc';

// 비밀번호 정의
const password = '123456789'

// 비밀번호로부터 키 파생
const key = crypto.scryptSync(password, 'TutorialsPoint', 24);

// 0으로 채워진 16바이트 iv 생성
const iv = Buffer.alloc(16, 0);

// cipher 객체 생성
const cipher = crypto.createCipheriv(algorithm, key, iv);

let encrypted = '';

// readable 이벤트로 데이터를 읽으며 암호화
cipher.on('readable', () => {
    let chunk;
    while (null !== (chunk = cipher.read())) {
      encrypted += chunk.toString('base64');
    }
});

// end 이벤트 처리
cipher.on('end', () => {
    console.log(encrypted);
});

// 데이터 쓰기 및 종료
cipher.write('TutorialsPoint');
cipher.end();
console.log("Completed... !");

실행 결과

C:\home\node>> node createCipheriv.js
Completed... !
uqeQEkXy5dpJjQv+JDvMHw==

두 번째 예제는 스트림 인터페이스를 활용하므로 파일이나 네트워크 데이터처럼 큰 용량의 데이터를 청크(chunk) 단위로 암호화할 때 특히 유용합니다. 'readable' 이벤트에서 데이터를 읽어 base64 형식으로 누적하고, 'end' 이벤트에서 최종 암호문을 출력합니다.

정리

crypto.createCipheriv()는 Node.js에서 대칭키 암호화를 구현할 때 가장 널리 사용되는 메서드입니다. 사용 시 주의할 점은 다음과 같습니다.

  • 키 길이는 반드시 알고리즘 요구 사항(aes-256은 32바이트, aes-192는 24바이트)과 일치해야 합니다.
  • 보안을 위해 iv는 매번 무작위로 생성하고, 복호화 시 사용할 수 있도록 암호문과 함께 저장해 두는 것이 좋습니다.
  • 레거시 메서드인 createCipher()는 안전하지 않으므로, 항상 createCipheriv()를 사용하는 것이 권장됩니다.