db 정보 조회
This commit is contained in:
113
backend-node/src/utils/passwordEncryption.ts
Normal file
113
backend-node/src/utils/passwordEncryption.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
// 비밀번호 암호화/복호화 유틸리티
|
||||
// 작성일: 2024-12-17
|
||||
|
||||
import crypto from "crypto";
|
||||
|
||||
export class PasswordEncryption {
|
||||
private static readonly ALGORITHM = "aes-256-cbc";
|
||||
private static readonly SECRET_KEY =
|
||||
process.env.DB_PASSWORD_SECRET ||
|
||||
"default-fallback-key-change-in-production";
|
||||
private static readonly IV_LENGTH = 16; // AES-CBC의 경우 16바이트
|
||||
|
||||
/**
|
||||
* 비밀번호를 암호화합니다.
|
||||
* @param password 암호화할 평문 비밀번호
|
||||
* @returns 암호화된 비밀번호 (base64 인코딩)
|
||||
*/
|
||||
static encrypt(password: string): string {
|
||||
try {
|
||||
// 랜덤 IV 생성
|
||||
const iv = crypto.randomBytes(this.IV_LENGTH);
|
||||
|
||||
// 암호화 키 생성 (SECRET_KEY를 해시하여 32바이트 키 생성)
|
||||
const key = crypto.scryptSync(this.SECRET_KEY, "salt", 32);
|
||||
|
||||
// 암호화 객체 생성
|
||||
const cipher = crypto.createCipher("aes-256-cbc", key);
|
||||
|
||||
// 암호화 실행
|
||||
let encrypted = cipher.update(password, "utf8", "hex");
|
||||
encrypted += cipher.final("hex");
|
||||
|
||||
// IV와 암호화된 데이터를 결합하여 반환
|
||||
return `${iv.toString("hex")}:${encrypted}`;
|
||||
} catch (error) {
|
||||
console.error("Password encryption failed:", error);
|
||||
throw new Error("비밀번호 암호화에 실패했습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 암호화된 비밀번호를 복호화합니다.
|
||||
* @param encryptedPassword 암호화된 비밀번호
|
||||
* @returns 복호화된 평문 비밀번호
|
||||
*/
|
||||
static decrypt(encryptedPassword: string): string {
|
||||
try {
|
||||
// IV와 암호화된 데이터 분리
|
||||
const parts = encryptedPassword.split(":");
|
||||
if (parts.length !== 2) {
|
||||
throw new Error("잘못된 암호화된 비밀번호 형식입니다.");
|
||||
}
|
||||
|
||||
const iv = Buffer.from(parts[0], "hex");
|
||||
const encrypted = parts[1];
|
||||
|
||||
// 암호화 키 생성 (암호화 시와 동일)
|
||||
const key = crypto.scryptSync(this.SECRET_KEY, "salt", 32);
|
||||
|
||||
// 복호화 객체 생성
|
||||
const decipher = crypto.createDecipher("aes-256-cbc", key);
|
||||
|
||||
// 복호화 실행
|
||||
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
||||
decrypted += decipher.final("utf8");
|
||||
|
||||
return decrypted;
|
||||
} catch (error) {
|
||||
console.error("Password decryption failed:", error);
|
||||
throw new Error("비밀번호 복호화에 실패했습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 암호화 키가 설정되어 있는지 확인합니다.
|
||||
* @returns 키 설정 여부
|
||||
*/
|
||||
static isKeyConfigured(): boolean {
|
||||
return (
|
||||
process.env.DB_PASSWORD_SECRET !== undefined &&
|
||||
process.env.DB_PASSWORD_SECRET !== ""
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 암호화/복호화 기능을 테스트합니다.
|
||||
* @returns 테스트 결과
|
||||
*/
|
||||
static testEncryption(): { success: boolean; message: string } {
|
||||
try {
|
||||
const testPassword = "test123!@#";
|
||||
const encrypted = this.encrypt(testPassword);
|
||||
const decrypted = this.decrypt(encrypted);
|
||||
|
||||
if (testPassword === decrypted) {
|
||||
return {
|
||||
success: true,
|
||||
message: "암호화/복호화 테스트가 성공했습니다.",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
message: "암호화/복호화 결과가 일치하지 않습니다.",
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: `암호화/복호화 테스트 실패: ${error}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user