/** * DOLCE 파일 다운로드용 DES 암호화 유틸리티 * Node.js crypto 모듈 사용 (OpenSSL 3.0 호환) */ import crypto from "crypto"; // 암호화 키 (8바이트) const DES_KEY = Buffer.from("4fkkdijg", "ascii"); /** * DES ECB 수동 구현 (OpenSSL 3.0 호환) * createCipher 대신 수동 블록 처리 */ function desEncryptBlock(block: Buffer, key: Buffer): Buffer { // DES 블록 암호화 (8바이트 블록) const cipher = crypto.createCipheriv("des-ecb", key, Buffer.alloc(0)); cipher.setAutoPadding(false); // 수동 패딩 return Buffer.concat([cipher.update(block), cipher.final()]); } /** * PKCS7 패딩 추가 */ function addPKCS7Padding(data: Buffer): Buffer { const blockSize = 8; const paddingLength = blockSize - (data.length % blockSize); const padding = Buffer.alloc(paddingLength, paddingLength); return Buffer.concat([data, padding]); } /** * PKCS7 패딩 제거 */ function removePKCS7Padding(data: Buffer): Buffer { const paddingLength = data[data.length - 1]; return data.slice(0, data.length - paddingLength); } /** * DES ECB 모드로 문자열 암호화 */ export function encryptDES(plainText: string): string { try { // UTF-8로 인코딩 let data = Buffer.from(plainText, "utf8"); // PKCS7 패딩 추가 data = addPKCS7Padding(data); // 8바이트 블록으로 분할하여 암호화 const encrypted: Buffer[] = []; for (let i = 0; i < data.length; i += 8) { const block = data.slice(i, i + 8); encrypted.push(desEncryptBlock(block, DES_KEY)); } // Base64 인코딩 const base64 = Buffer.concat(encrypted).toString("base64"); // + 문자를 ||| 로 변환 return base64.replace(/\+/g, "|||"); } catch (error) { console.error("DES 암호화 실패:", error); throw new Error(`암호화 중 오류가 발생했습니다: ${error}`); } } /** * DES ECB 모드로 문자열 복호화 */ export function decryptDES(encryptedText: string): string { try { // ||| 를 + 로 복원 const restored = encryptedText.replace(/\|\|\|/g, "+"); // Base64 디코딩 const data = Buffer.from(restored, "base64"); // 8바이트 블록으로 분할하여 복호화 const decrypted: Buffer[] = []; for (let i = 0; i < data.length; i += 8) { const block = data.slice(i, i + 8); const decipher = crypto.createDecipheriv("des-ecb", DES_KEY, Buffer.alloc(0)); decipher.setAutoPadding(false); decrypted.push(Buffer.concat([decipher.update(block), decipher.final()])); } // PKCS7 패딩 제거 const unpaddedData = removePKCS7Padding(Buffer.concat(decrypted)); // UTF-8 디코딩 return unpaddedData.toString("utf8").replace(/\0+$/, ""); } catch (error) { console.error("DES 복호화 실패:", error); throw new Error(`복호화 중 오류가 발생했습니다: ${error}`); } } /** * DOLCE 파일 다운로드용 암호화 키 생성 */ export function createDolceDownloadKey( fileId: string, userId: string, fileName: string ): string { const plainText = `${fileId}↔${userId}↔${fileName}`; 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, }; }