diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-24 10:41:46 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-24 10:41:46 +0900 |
| commit | 26365ef08588d53b8c5d9c7cfaefb244536e6743 (patch) | |
| tree | 979841b791d1c3925eb1c3efa3f901f2c0bef193 /lib/dolce/crypto-utils.ts | |
| parent | fd4909bba7be8abc1eeab9ae1b4621c66a61604a (diff) | |
(김준회) 돌체 재개발 - 2차: 업로드 개선, 다운로드 오류 수정
Diffstat (limited to 'lib/dolce/crypto-utils.ts')
| -rw-r--r-- | lib/dolce/crypto-utils.ts | 107 |
1 files changed, 61 insertions, 46 deletions
diff --git a/lib/dolce/crypto-utils.ts b/lib/dolce/crypto-utils.ts index 1fb310b2..0a3f18c5 100644 --- a/lib/dolce/crypto-utils.ts +++ b/lib/dolce/crypto-utils.ts @@ -4,7 +4,8 @@ * * OpenSSL 3.0 호환 처리: * - Node.js 17+ 환경에서 DES는 레거시 알고리즘으로 분류됨 - * - 에러 발생 시 crypto-utils-legacy.ts의 수동 구현 사용 + * - 기본적으로 crypto-js 기반 구현 사용 (OpenSSL 독립적) + * - 환경 변수로 Native crypto 사용 가능: USE_NATIVE_CRYPTO=true */ import crypto from "crypto"; @@ -12,8 +13,11 @@ import crypto from "crypto"; // 암호화 키 (8바이트) const DES_KEY = Buffer.from("4fkkdijg", "ascii"); +// OpenSSL Native Crypto 사용 여부 (기본: false, crypto-js 사용) +const USE_NATIVE_CRYPTO = process.env.USE_NATIVE_CRYPTO === "true"; + // OpenSSL 3.0 환경 감지 -let useModernCrypto = true; +let useModernCrypto = USE_NATIVE_CRYPTO; /** * DES ECB 모드로 문자열 암호화 @@ -21,40 +25,44 @@ let useModernCrypto = true; * @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 { + // 기본적으로 레거시 구현(crypto-js) 사용 + if (!useModernCrypto) { return encryptDESLegacy(plainText); } + + // Native crypto 시도 (USE_NATIVE_CRYPTO=true인 경우만) + 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 에러 감지 - 레거시로 폴백 + if ( + error.code === "ERR_OSSL_EVP_UNSUPPORTED" || + error.message?.includes("unsupported") || + error.message?.includes("digital envelope") + ) { + console.warn("[DOLCE] OpenSSL DES 미지원, crypto-js로 전환합니다."); + useModernCrypto = false; + return encryptDESLegacy(plainText); + } + throw error; + } } /** - * 레거시 DES 암호화 (OpenSSL 3.0 대체) + * 레거시 DES 암호화 (crypto-js 기반, OpenSSL 독립적) */ function encryptDESLegacy(plainText: string): string { try { const { encryptDES: legacyEncrypt } = require("./crypto-utils-legacy"); return legacyEncrypt(plainText); } catch (error) { - console.error("DES 암호화 실패:", error); + console.error("[DOLCE] DES 암호화 실패:", error); throw new Error(`암호화 중 오류가 발생했습니다: ${error}`); } } @@ -65,38 +73,45 @@ function encryptDESLegacy(plainText: string): string { * @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 { + // 기본적으로 레거시 구현(crypto-js) 사용 + if (!useModernCrypto) { return decryptDESLegacy(encryptedText); } + + // Native crypto 시도 (USE_NATIVE_CRYPTO=true인 경우만) + 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) { + // OpenSSL 에러 감지 - 레거시로 폴백 + if ( + error.code === "ERR_OSSL_EVP_UNSUPPORTED" || + error.message?.includes("unsupported") || + error.message?.includes("digital envelope") + ) { + console.warn("[DOLCE] OpenSSL DES 미지원, crypto-js로 전환합니다."); + useModernCrypto = false; + return decryptDESLegacy(encryptedText); + } + throw error; + } } /** - * 레거시 DES 복호화 (OpenSSL 3.0 대체) + * 레거시 DES 복호화 (crypto-js 기반, OpenSSL 독립적) */ function decryptDESLegacy(encryptedText: string): string { try { const { decryptDES: legacyDecrypt } = require("./crypto-utils-legacy"); return legacyDecrypt(encryptedText); } catch (error) { - console.error("DES 복호화 실패:", error); + console.error("[DOLCE] DES 복호화 실패:", error); throw new Error(`복호화 중 오류가 발생했습니다: ${error}`); } } |
