/** * DOLCE 파일 다운로드용 DES 암호화 유틸리티 * C# DESCryptoServiceProvider와 호환되는 Node.js 구현 * * OpenSSL 3.0 호환 처리: * - Node.js 17+ 환경에서 DES는 레거시 알고리즘으로 분류됨 * - 에러 발생 시 crypto-utils-legacy.ts의 수동 구현 사용 */ import crypto from "crypto"; // 암호화 키 (8바이트) const DES_KEY = Buffer.from("4fkkdijg", "ascii"); // OpenSSL 3.0 환경 감지 let useModernCrypto = true; /** * DES ECB 모드로 문자열 암호화 * @param plainText 암호화할 평문 * @returns Base64 인코딩된 암호문 */ export function encryptDES(plainText: string): string { // 처음 호출 시 OpenSSL 지원 여부 확인 if (useModernCrypto) { try { const cipher = crypto.createCipheriv("des-ecb", DES_KEY, Buffer.alloc(0)); cipher.setAutoPadding(true); let encrypted = cipher.update(plainText, "utf8", "base64"); encrypted += cipher.final("base64"); return encrypted.replace(/\+/g, "|||"); } catch (error: any) { // OpenSSL 3.0 에러 감지 if (error.message?.includes("unsupported") || error.message?.includes("digital envelope")) { console.warn("[DOLCE] OpenSSL 3.0 감지, 레거시 구현으로 전환합니다."); useModernCrypto = false; // 레거시 구현으로 재시도 return encryptDESLegacy(plainText); } throw error; } } else { return encryptDESLegacy(plainText); } } /** * 레거시 DES 암호화 (OpenSSL 3.0 대체) */ function encryptDESLegacy(plainText: string): string { try { const { encryptDES: legacyEncrypt } = require("./crypto-utils-legacy"); return legacyEncrypt(plainText); } catch (error) { console.error("DES 암호화 실패:", error); throw new Error(`암호화 중 오류가 발생했습니다: ${error}`); } } /** * DES ECB 모드로 문자열 복호화 * @param encryptedText Base64 인코딩된 암호문 * @returns 복호화된 평문 */ export function decryptDES(encryptedText: string): string { if (useModernCrypto) { try { const restored = encryptedText.replace(/\|\|\|/g, "+"); const decipher = crypto.createDecipheriv("des-ecb", DES_KEY, Buffer.alloc(0)); decipher.setAutoPadding(true); let decrypted = decipher.update(restored, "base64", "utf8"); decrypted += decipher.final("utf8"); return decrypted.replace(/\0+$/, ""); } catch (error: any) { if (error.message?.includes("unsupported") || error.message?.includes("digital envelope")) { console.warn("[DOLCE] OpenSSL 3.0 감지, 레거시 구현으로 전환합니다."); useModernCrypto = false; return decryptDESLegacy(encryptedText); } throw error; } } else { return decryptDESLegacy(encryptedText); } } /** * 레거시 DES 복호화 (OpenSSL 3.0 대체) */ function decryptDESLegacy(encryptedText: string): string { try { const { decryptDES: legacyDecrypt } = require("./crypto-utils-legacy"); return legacyDecrypt(encryptedText); } catch (error) { console.error("DES 복호화 실패:", error); throw new Error(`복호화 중 오류가 발생했습니다: ${error}`); } } /** * DOLCE 파일 다운로드용 암호화 키 생성 * @param fileId 파일 ID * @param userId 사용자 ID * @param fileName 파일명 * @returns 암호화된 키 */ export function createDolceDownloadKey( fileId: string, userId: string, fileName: string ): string { // FileId↔UserId↔FileName 형식으로 조합 const plainText = `${fileId}↔${userId}↔${fileName}`; // DES 암호화 return encryptDES(plainText); } /** * 테스트용: 암호화/복호화 검증 */ export function testDESEncryption(testString: string): { original: string; encrypted: string; decrypted: string; match: boolean; } { const encrypted = encryptDES(testString); const decrypted = decryptDES(encrypted); return { original: testString, encrypted, decrypted, match: testString === decrypted, }; }