Node.js에서 cipher.final() 메서드는 암호화(cipher) 객체의 최종 결과 값을 Buffer 또는 String 형태로 반환하는 데 사용됩니다. 이 메서드는 crypto 모듈 내 Cipher 클래스가 기본적으로 제공하는 내장 메서드 중 하나입니다.
주요 동작 방식은 다음과 같습니다.
- 출력 인코딩(outputEncoding)을 지정하면 문자열(String)을 반환합니다.
- 출력 인코딩을 지정하지 않으면 Buffer 객체를 반환합니다.
- cipher.final() 메서드를 두 번 이상 호출하면 에러가 발생합니다.
문법(Syntax)
cipher.final([outputEncoding])
매개변수(Parameters)
outputEncoding – 출력 인코딩 방식을 나타내는 매개변수로, 문자열(string) 타입입니다. 사용 가능한 값으로는 hex, base64 등이 있습니다.
예제 1: 인코딩 지정하여 결과 출력하기
cipherFinal.js라는 이름의 파일을 생성하고 아래 코드를 복사한 후, 다음 명령어로 실행해 보겠습니다.
node cipherFinal.js
// cipher.final() 메서드 사용 예제
// crypto 모듈 불러오기
const crypto = require('crypto');
// AES 알고리즘 초기화
const algorithm = 'aes-192-cbc';
// 키 생성에 사용할 비밀번호 설정
const password = '12345678';
// 암호화 객체에 사용할 키 생성
const key = crypto.scryptSync(password, 'salt', 24);
// 고정 IV(초기화 벡터) 생성
const iv = Buffer.alloc(16, 0);
// 암호화 객체 생성
const cipher = crypto.createCipheriv(algorithm, key, iv);
const cipher2 = crypto.createCipheriv(algorithm, key, iv);
// outputEncoding이 지정되어 있으므로 문자열로 반환됨
let hexValue = cipher.final('hex');
let base64Value = cipher2.final('base64');
// 결과 출력
console.log("Hex String:- " + hexValue);
console.log("Base64 String:- " + base64Value)실행 결과
C:\home\node>> node cipherFinal.js Hex String:- 8d11772fce59f08e7558db5bf17b3112 Base64 String:- jRF3L85Z8I51WNtb8XsxEg==
위 예제에서 볼 수 있듯이, 인코딩을 'hex'로 지정하면 16진수 문자열이, 'base64'로 지정하면 Base64 인코딩된 문자열이 반환됩니다.
예제 2: final() 재호출 시 에러 발생 확인하기
이번에는 같은 암호화 객체에서 final() 메서드를 여러 번 호출했을 때 어떤 일이 발생하는지 살펴보겠습니다.
// cipher.final() 메서드 사용 예제
// crypto 모듈 불러오기
const crypto = require('crypto');
// AES 알고리즘 초기화
const algorithm = 'aes-192-cbc';
// 키 생성에 사용할 비밀번호 설정
const password = '12345678';
// scrypt 콜백 방식으로 키 생성
crypto.scrypt(password, 'salt', 24,
{ N: 512 }, (err, key) => {
if (err) throw err;
// 고정 IV(초기화 벡터) 생성
const iv = Buffer.alloc(16, 0);
// 암호화 객체 생성
const cipher = crypto.createCipheriv(algorithm, key, iv);
// outputEncoding이 없으므로 Buffer로 반환됨
let hexValue = cipher.final();
// 이미 final()이 호출되었으므로 에러 발생!
let base64Value = cipher.final('base64');
// 결과 출력
console.log("Buffer:- " + hexValue);
console.log("Base64 String:- " + base64Value)
});실행 결과
C:\home\node>> node cipherFinal.js
internal/crypto/cipher.js:164
const ret = this._handle.final();
^
Error: Unsupported state
at Cipheriv.final (internal/crypto/cipher.js:164:28)
at Object. (/home/node/test/cipher.js:22:26)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:20)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)에러 원인 분석
위 예제에서 에러가 발생한 이유는 이미 해당 키로 final() 메서드가 한 번 호출되었기 때문입니다. final()은 말 그대로 암호화 과정을 종료하는 마지막 단계 메서드이므로, 동일한 암호화 객체에서 두 번째 호출 시 더 이상 처리할 데이터 상태가 없어 Error: Unsupported state 예외가 발생하게 됩니다.
따라서 실무에서는 하나의 암호화 객체당 final()을 반드시 한 번만 호출하도록 주의해야 하며, 추가 암호화 작업이 필요하다면 새로운 cipher 객체를 생성해야 합니다.