반응형
전자정부프레임워크 기반의 애플리케이션에서 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 적용 방식:
- 인증서 발급
- 서버 설정
- HTTPS 사용
2-2. HTTPS 적용
전자정부프레임워크 프로젝트에서 HTTPS를 설정하려면 인증서 발급과 서버 설정이 필요합니다.
- 로컬 인증서 발급
OpenSSL을 사용하여 자체 서명된 인증서를 생성합니다.생성된 cert.pem과 key.pem을 서버에서 사용합니다. - openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
- Tomcat HTTPS 설정
server.xml 파일에서 HTTPS 커넥터를 추가합니다. - <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="200" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="keystore.jks" type="RSA" /> </SSLHostConfig> </Connector>
- 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. 테스트
- HTTPS로 애플리케이션에 접속합니다.
- AES 또는 RSA 암호화를 사용하여 데이터를 암호화하고, 서버에서 복호화된 데이터를 확인합니다.
- 네트워크 통신 중 데이터를 캡처하여 암호화된 상태를 확인합니다.
5. 마무리
오늘 학습한 SSL/TLS 설정과 데이터 암호화 방식은 API 서버와 클라이언트 간 안전한 통신의 기본입니다. 다음에서는 OAuth2를 활용한 소셜 로그인 구현에 대해 학습합니다.
반응형
'개발 > 전자정부프레임워크' 카테고리의 다른 글
OAuth 2.0 기반 API 요청 및 Access Token 검증 (0) | 2024.12.26 |
---|---|
OAuth 2.0을 이용한 소셜 로그인 구현 (0) | 2024.12.26 |
JWT(JSON Web Token)를 활용한 토큰 기반 인증 (0) | 2024.12.26 |
Spring Security를 활용한 인증 및 권한 관리 (0) | 2024.12.26 |
RESTful 웹 서비스 개발 (0) | 2024.12.25 |