์ต๊ทผ BoB ๋ฉด์ ์ ์ค๋นํ๋ฉด์ ์ง๋ ํ๋ก์ ํธ๋ค์ ๋๋์๋ณด๊ณ ์์๋ค.
๋ด ์ง๋ ํ๋ก์ ํธ ์ค์ ํ๊ณผ ์ฐ๊ตฌ์ค์์ ํ์ฌ ์กธ์ ๋ ผ๋ฌธ์ ์ฐธ์ฌํด์ ํ์ผ ์๋ณตํธํ ๋ชจ๋์ ๊ตฌํํ๋ ๊ฒฝํ์ด ์๋ค.
ํ์ฌ ํด๋น ํ๋ก๊ทธ๋จ์ ์์ค ์ฝ๋๋ ๋ณด์์ ๊ณต๊ฐ๋์ด ์์ง ์๊ณ ๋๋ 2๋ ์ ์ ํ๋ก์ ํธ๋ผ์ ๊ธฐ์ต์ด ์ ๋์ง ์์๋ค.
๊ทธ๋์ ์ต๋ํ ๊ทธ ๊ธฐ์ต์ ๋๋ฌ์ด ํ์ผ ์๋ณตํธํ ๋ชจ๋์ ๋ค์ ๊ตฌํํ๋ ค ํ๋๋ฐ, ์๊ฐ๋ณด๋ค ํ๊ธ๋ก ๋ ์๋ฃ๊ฐ ๋ง์ง ์์ ๋ค๋ฅธ ์ฌ๋๋ค์๊ฒ ๊ณต์ ํ๋ค๋ฉด ๊ฝค ๋์ ๋ ๊ฒ ๊ฐ์์ ๊ทธ ๊ณผ์ ์ ํ ๋ฒ ํฌ์คํ ํ๋ ค ํ๋ค.
๋ชฉ์ฐจ
- Bouncy Castle
- ๋ธ๋ก ์ํธ, SEED ์๊ณ ๋ฆฌ์ฆ์ด๋?
- ํ๋ก์ ํธ ์์ฑ
- ํ๋ก์ ํธ ์์ฑ
- ์์กด์ฑ ์ถ๊ฐ
FileUtil.class
๊ตฌํBouncyModule.class
๊ตฌํEncryption.class
๊ตฌํ
- ํ ์คํธ
Bouncy Castle
์ฐ์ ๋๋ ํ์ผ ์ํธํ ๋ณตํธํ๋ฅผ ์ํด Bouncy Castle ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ๊ฒ์ด๋ค.
Bouncy Castle์ ์ ๋ช ํ ์ํธํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก Java, C# ๋ฒ์ ์ ๋ฐ๋ผ ๋ฐฐํฌ๋๋ค.
- Bouncy Castle ๊ณต์ ํํ์ด์ง
๋์นญํค ์ํธ, ๋ธ๋ก ์ํธ, SEED ์๊ณ ๋ฆฌ์ฆ์ด๋?
์ฐ๋ฆฌ๋ Bouncy Castle ๋ก ์ํธํ๋ฅผ ์ํํ ๊ฒ์ธ๋ฐ, ์ค์ง์ ์ผ๋ก ์ํธํ๋ฅผ ์ํํ ์๊ณ ๋ฆฌ์ฆ์ ๋์นญํค ์ํธ ์์คํ ์ ์ด์ฉํ ๊ฒ์ด๋ค.
๋์นญํค ์ํธ๋ ์ํธํ ํค์ ๋ณตํธํ ํค๊ฐ ๋์ผํ ์ํธ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๋์นญ ํค ์ํธ ์์คํ ์์๋ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ๋ํ์ ์ด๋ค.
- ๋ฐ์ดํฐ๋ฅผ ๋ธ๋ก ๋จ์๋ก ์ํธํ : ๋ธ๋ก ์ํธ
- ๋ฐ์ดํฐ๋ฅผ ์คํธ๋ฆผ ๋จ์๋ก ์ํธํ : ์คํธ๋ฆผ ์ํธ
๋ธ๋ก ์ํธ๋?
๋ํ์ ์ธ ๋ธ๋ก ์ํธ์ ๊ตฌ์กฐ๋ Feistal ๊ณผ SPN ๊ตฌ์กฐ๊ฐ ์กด์ฌํ๋๋ฐ, ์ฐ๋ฆฌ๋ ํ์ด์คํ ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ๋ ค ํ๋ค.
ํ์ด์คํ ๊ตฌ์กฐ๋ ๋ผ์ด๋ ํจ์๊ฐ ๋ฐ๋ณต์ ์ผ๋ก ์ ์ฉ๋๋ ๊ตฌ์กฐ๋ก ๋ํ์ ์ผ๋ก๋ DES์ ๊ตญ์ฐ ์ ํ์ธ SEED๊ฐ ์กด์ฌํ๋ค.
์ฐธ๊ณ ๋ก SPN ๊ตฌ์กฐ๋ ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ AES๊ฐ ์กด์ฌํ๋ค
์ฐ๋ผ๋ ๋ธ๋ก ์ํธ์ SEED ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ค ํ๋ค.
SEED ์๊ณ ๋ฆฌ์ฆ์ด๋?
SEED ์๊ณ ๋ฆฌ์ฆ์ 1999๋ 2์ ํ๊ตญ์ธํฐ๋ท์งํฅ ์๊ณผ ๊ตญ๋ด ์ํธ์ ๋ฌธ๊ฐ๋ค์ด ์์ ๊ตญ๋ด๊ธฐ์ ๋ก ๊ฐ๋ฐํ 128๋นํธ ๋ธ๋ก ์ํธ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
1999๋ ๊ฐ๋ฐ๋์๋๋ฐ 2005๋ ๊ตญ์ ํ์คํ ๊ธฐ๊ตฌ์ธ ISO/IEC ๊ตญ์ ๋ธ๋ก์ํธ์๊ณ ๋ฆฌ์ฆ IETFํ์ค์ผ๋ก ์ ์ ๋์๋ค.
์ด์ ์ด๋ ์ ๋ ๊ธฐ๋ณธ์ ๋์์ผ๋ ํ๋ก์ ํธ๋ฅผ ์ค์ ๋ก ๋ง๋ค์ด๋ณด์!
ํ๋ก์ ํธ ์์ฑ
ํ๋ก์ ํธ๋ Gradle ํ๋ก์ ํธ๋ก ์์ฑํ๋๋ก ํ์!
๊ทธ๋ฆฌ๊ณ Bouncy Castle ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ์ build.gradle ์ ์ถ๊ฐํด์ฃผ์!
dependencies {
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.68'
}
๊ทธ๋ฆฌ๊ณ ์๋ ๊ธฐ์ ๋ ๋ด์ฉ๋๋ก ์ ๊ตฌํํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊ฐ๊ฒ ๋ ๊ฒ์ด๋ค
FileUtil.java ๊ตฌํ
ํด๋น ํด๋์ค๋ ์ํธํํ ํ์ผ์ ๋ถ๋ฌ์ค๊ณ , ์ํธํ๋ ํ์ผ์ ์ ์ฅํ ์ ํธ ํด๋์ค์ด๋ค.
public class FileUtil {
private FileInputStream fileInputStream;
private FileOutputStream fileOutputStream;
public byte[] getFileBytesFrom(String path) throws IOException {
// ํ์ผ ๊ฐ์ฒด ์์ฑ
File file = new File(path);
fileInputStream = new FileInputStream(file);
byte[] fileBytes = new byte[(int)file.length()];
fileInputStream.read(fileBytes);
fileInputStream.close();
return fileBytes;
}
public void saveFile(String path, byte[] fileData) throws IOException {
fileOutputStream = new FileOutputStream(path);
fileOutputStream.write(fileData);
fileOutputStream.close();
}
}
BouncyModule.java ๊ตฌํ
์ด์ ์ค์ ๋ก BouncyCastle ๋ก ๋ธ๋ก ์ํธ๋ฅผ ์ด์ฉํด์ ํ์ผ์ ์ํธํ ํด๋ณด์
public class BouncyModule {
public byte[] encrypt(String key, byte[] plainText) {
byte[] keyBytes = key.getBytes();
// ๋ธ๋ก ์ํธ ์ด์ฉ
// ๋ธ๋ก๋ณด๋ค ๋ฐ์ดํฐ๊ฐ ์งง์ ๊ฒฝ์ฐ ํจ๋ฉ์ ์ฌ์ฉํจ
// ๋ธ๋ก ์ํธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก๋ SEED ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํจ
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new SEEDEngine());
// ์ด๊ธฐํ ๋ฐ ํค ํ๋ผ๋ฏธํฐ ์์ฑ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๊ฐ true ๋ผ๋ฉด ์ํธํ ๋ชจ๋
cipher.init(true, new KeyParameter(keyBytes));
return getBytes(plainText, cipher);
}
public byte[] decrypt(String key, byte[] cipherText) {
byte[] keyBytes = key.getBytes();
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new SEEDEngine());
cipher.init(false, new KeyParameter(keyBytes));
return getBytes(cipherText, cipher);
}
private byte[] getBytes(byte[] targetData, BufferedBlockCipher cipher) {
byte[] outputData = new byte[cipher.getOutputSize(targetData.length)];
int tam = cipher.processBytes(targetData, 0, targetData.length, outputData, 0);
try {
cipher.doFinal(outputData, tam);
} catch (Exception e) {
e.printStackTrace();
}
return outputData;
}
}
๋ชจ๋๋ ๋ธ๋ก ์ํธ ๋ชจ๋๋ฅผ ์ด์ฉํ๋ค.
๋ง์ฝ ๋ธ๋ก๋ณด๋ค ๋ฐ์ดํฐ์ ๊ธธ์ด๊ฐ ์งง์ ๊ฒฝ์ฐ ํจ๋ฉ์ ์ฌ์ฉํ๊ณ , ๋ธ๋ก ์ํธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก SEED ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ค๊ณ ์ง์ ํด์ค๋ค.
EncryptUtil.java ๊ตฌํ
์์์์ ์์ฑํ ํ์ผ ์ ํธ๊ณผ bouncy castle ๋ชจ๋์ ์ด์ฉํด์ ์ํธํ ์ ํธ์ ๊ตฌํํด๋ณด์
public class EncryptUtil {
private static BouncyModule bouncyModule = new BouncyModule();
private static FileUtil fileUtil = new FileUtil();
public static void encryption(String key, String filePath) throws IOException {
byte[] plainFileBytes = fileUtil.getFileBytesFrom(filePath);
byte[] encryptedFileBytes = bouncyModule.encrypt(key, plainFileBytes);
fileUtil.saveFile(filePath, encryptedFileBytes);
}
public static void decryption(String key, String filePath) throws IOException {
byte[] encryptedFileBytes = fileUtil.getFileBytesFrom(filePath);
byte[] decryptedFile = bouncyModule.decrypt(key, encryptedFileBytes);
fileUtil.saveFile(filePath, decryptedFile);
}
}
ํ ์คํธ
์ด์ ๊ตฌํ์ด ๋๋ฌ์ผ๋ ํ์ผ ํ๋๋ฅผ ์ก๊ณ ํ ์คํธํด๋ณด์
๋๋ ๋ฐํํ๋ฉด์ ์๋ ํ๊ต ๋ก๊ณ png ํ์ผ์ ์ํธํ ํด๋ณด๋๋ก ํ๊ฒ ๋ค!
์ํธํ๋ฅผ ํ๊ธฐ ์ ์๋ ํ์ผ์ด ์ ์ด๋ฆฐ๋ค.
์ด์ main ํจ์์์ ์ํธํ๋ฅผ ์ํํ์
public class Main {
public static void main(String[] args) throws Exception {
String key = "$2a$10$mxLAM1fAEDPWkFz83IPDH.7yvyY6njmIMSk937jdH9UD3HhbqYPgO";
String path = "/Users/my/Desktop/logo.png";
EncryptUtil.encryption(key, path);
}
}
๊ทธ๋ผ ๋ค์๊ณผ ๊ฐ์ด ํ์ผ์ ์ด ์ ์๋ค๊ณ ๋์จ๋ค
๊ทธ๋ฆฌ๊ณ ๋ณตํธํ๋ฅผ ์ํํด๋ณด์
public class Main {
public static void main(String[] args) throws Exception {
// key ์์ฑ (60 ๊ธธ์ด)
String key = "$2a$10$mxLAM1fAEDPWkFz83IPDH.7yvyY6njmIMSk937jdH9UD3HhbqYPgO";
String path = "/Users/jangwonik/Desktop/logo.png";
// EncryptUtil.encryption(key, path);
EncryptUtil.decryption(key, path);
}
}
๊ทธ๋ผ ๋ค์๊ณผ ๊ฐ์ด ๋ค์ ํ์ผ์ ์ด ์ ์๊ฒ ๋์๋ค!
๋๊ธ