1
2const fs = require('fs');
3const crypto = require('crypto');
4
5
6const EncryptionMethod = {
7 NONE: 0,
8 AES_CBC: 1,
9};
10
11
12function createContainer({ imagePath, containerPath, encryptionMethod, secretKey }) {
13 const imageData = fs.readFileSync(imagePath);
14 let encryptedData;
15
16 if (encryptionMethod === EncryptionMethod.NONE) {
17
18 encryptedData = imageData;
19 } else if (encryptionMethod === EncryptionMethod.AES_CBC) {
20 const iv = crypto.randomBytes(16);
21 const cipher = crypto.createCipheriv('aes-256-cbc', secretKey, iv);
22 encryptedData = Buffer.concat([iv, cipher.update(imageData), cipher.final()]);
23 } else {
24 throw new Error('지원하지 않는 암호화 방식');
25 }
26
27
28 const header = Buffer.alloc(20);
29 header.write('CIMG', 0, 4, 'utf8');
30 header.writeInt32BE(1, 4);
31 header.writeInt32BE(encryptionMethod, 8);
32
33
34
35 const containerData = Buffer.concat([header, encryptedData]);
36 fs.writeFileSync(containerPath, containerData);
37}
38
39
40function extractImage({ containerPath, outputImagePath, secretKey }) {
41 const containerData = fs.readFileSync(containerPath);
42
43
44 const magic = containerData.slice(0, 4).toString('utf8');
45 if (magic !== 'CIMG') throw new Error('유효하지 않은 컨테이너');
46 const encryptionMethod = containerData.readInt32BE(8);
47
48
49 let encryptedData = containerData.slice(20);
50 let imageData;
51
52 if (encryptionMethod === EncryptionMethod.NONE) {
53 imageData = encryptedData;
54 } else if (encryptionMethod === EncryptionMethod.AES_CBC) {
55 const iv = encryptedData.slice(0, 16);
56 const actualEncrypted = encryptedData.slice(16);
57 const decipher = crypto.createDecipheriv('aes-256-cbc', secretKey, iv);
58 imageData = Buffer.concat([decipher.update(actualEncrypted), decipher.final()]);
59 } else {
60 throw new Error('지원하지 않는 암호화 방식');
61 }
62
63 fs.writeFileSync(outputImagePath, imageData);
64}
65
66
67