1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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,
};
}
|