반응형

전자정부프레임워크 기반의 애플리케이션에서 API 서버와 클라이언트 간의 통신을 데이터 암호화를 통해 보호하는 방법을 학습합니다. SSL/TLS 설정과 함께 데이터 암호화를 적용하여 중요한 데이터를 안전하게 전송할 수 있도록 구현합니다.


1. 데이터 암호화란?

  • 데이터 암호화는 민감한 정보를 보호하기 위해 데이터를 변환하여 권한이 없는 사용자가 읽을 수 없도록 만드는 과정입니다.
  • 전송 중 데이터를 암호화함으로써 **중간자 공격(Man-in-the-Middle Attack)**을 방지할 수 있습니다.

2. SSL/TLS를 이용한 통신 암호화

2-1. SSL/TLS란?

SSL(Secure Sockets Layer)과 TLS(Transport Layer Security)는 데이터를 암호화하여 클라이언트와 서버 간의 안전한 통신을 제공합니다.

  • SSL/TLS 적용 방식:
    1. 인증서 발급
    2. 서버 설정
    3. HTTPS 사용

2-2. HTTPS 적용

전자정부프레임워크 프로젝트에서 HTTPS를 설정하려면 인증서 발급과 서버 설정이 필요합니다.

  1. 로컬 인증서 발급
    OpenSSL을 사용하여 자체 서명된 인증서를 생성합니다.생성된 cert.pem과 key.pem을 서버에서 사용합니다.
  2. openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
  3. Tomcat HTTPS 설정
    server.xml 파일에서 HTTPS 커넥터를 추가합니다.
  4. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="200" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="keystore.jks" type="RSA" /> </SSLHostConfig> </Connector>
  5. HTTPS로 애플리케이션 접속
    브라우저에서 https://localhost:8443를 사용하여 애플리케이션에 접속합니다.

3. 데이터 암호화 및 복호화 구현

3-1. 대칭키 암호화

대칭키 암호화는 암호화와 복호화에 동일한 키를 사용하는 방식입니다. AES 알고리즘을 활용하여 데이터를 암호화합니다.

AESUtil.java

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AESUtil {

    private static final String ALGORITHM = "AES";

    public static String encrypt(String data, String secretKey) throws Exception {
        SecretKey key = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    public static String decrypt(String encryptedData, String secretKey) throws Exception {
        SecretKey key = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        byte[] originalData = cipher.doFinal(decodedData);
        return new String(originalData);
    }
}

테스트 코드:

public class AESUtilTest {
    public static void main(String[] args) throws Exception {
        String secretKey = "1234567890123456"; // 16자리 키
        String originalData = "Hello, Secure World!";

        String encryptedData = AESUtil.encrypt(originalData, secretKey);
        System.out.println("Encrypted Data: " + encryptedData);

        String decryptedData = AESUtil.decrypt(encryptedData, secretKey);
        System.out.println("Decrypted Data: " + decryptedData);
    }
}

3-2. 공개키 암호화

공개키 암호화는 데이터 암호화와 복호화에 각각 다른 키(공개키와 개인키)를 사용하는 방식입니다. RSA 알고리즘을 활용하여 데이터를 암호화합니다.

RSAUtil.java

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class RSAUtil {

    private static final String ALGORITHM = "RSA";

    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyGen.initialize(2048);
        return keyGen.generateKeyPair();
    }

    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }

    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        return new String(cipher.doFinal(decodedData));
    }
}

테스트 코드:

public class RSAUtilTest {
    public static void main(String[] args) throws Exception {
        KeyPair keyPair = RSAUtil.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String originalData = "Hello, Secure World!";
        String encryptedData = RSAUtil.encrypt(originalData, publicKey);
        System.out.println("Encrypted Data: " + encryptedData);

        String decryptedData = RSAUtil.decrypt(encryptedData, privateKey);
        System.out.println("Decrypted Data: " + decryptedData);
    }
}

4. 테스트

  1. HTTPS로 애플리케이션에 접속합니다.
  2. AES 또는 RSA 암호화를 사용하여 데이터를 암호화하고, 서버에서 복호화된 데이터를 확인합니다.
  3. 네트워크 통신 중 데이터를 캡처하여 암호화된 상태를 확인합니다.

5. 마무리

오늘 학습한 SSL/TLS 설정데이터 암호화 방식은 API 서버와 클라이언트 간 안전한 통신의 기본입니다. 다음에서는 OAuth2를 활용한 소셜 로그인 구현에 대해 학습합니다.

반응형

+ Recent posts