diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-23 16:40:37 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-23 16:40:37 +0900 |
| commit | fd4909bba7be8abc1eeab9ae1b4621c66a61604a (patch) | |
| tree | d375995611de80b55b344b1c536c5a760f06ccb6 /lib/dolce/crypto-utils-legacy.ts | |
| parent | a2e0785c8749c4d3766ecf3b70edfb7c2fe4df20 (diff) | |
(김준회) 돌체 재개발 - 1차 (다운로드 오류 수정 필요)
Diffstat (limited to 'lib/dolce/crypto-utils-legacy.ts')
| -rw-r--r-- | lib/dolce/crypto-utils-legacy.ts | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/dolce/crypto-utils-legacy.ts b/lib/dolce/crypto-utils-legacy.ts new file mode 100644 index 00000000..c5ee496f --- /dev/null +++ b/lib/dolce/crypto-utils-legacy.ts @@ -0,0 +1,131 @@ +/** + * 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, + }; +} + |
