[Java] Bouncy Castle λΌμ΄λΈλ¬λ¦¬λ₯Ό μ΄μ©νμ¬ νμΌ μνΈν, 볡νΈν νκΈ° (feat.λΈλ‘ μνΈμ SEED μκ³ λ¦¬μ¦)
μ΅κ·Ό 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);
}
}
κ·ΈλΌ λ€μκ³Ό κ°μ΄ λ€μ νμΌμ μ΄ μ μκ² λμλ€!