2025-03-12T10:43:35
This commit is contained in:
263
docs/security/bouncy castle.md
Normal file
263
docs/security/bouncy castle.md
Normal file
@@ -0,0 +1,263 @@
|
||||
자바의 **Java Security API**(JCA 및 JCE 포함)는 암호화, 인증, 키 관리 등 보안 기능을 제공하는 다양한 클래스를 포함하고 있습니다. 여기서는 자바 시큐리티에서 자주 사용되는 주요 클래스와 그 역할에 대해 설명하고, 각 클래스의 주요 메서드를 표로 정리하겠습니다.
|
||||
|
||||
---
|
||||
|
||||
### **주요 클래스와 역할**
|
||||
1. **`java.security.MessageDigest`**
|
||||
- **역할**: 해시 함수(MD5, SHA-1, SHA-256 등)를 사용하여 데이터의 메시지 다이제스트(해시 값)를 생성. 데이터 무결성 확인에 사용.
|
||||
- **특징**: 단방향 함수로, 입력 데이터를 고정된 길이의 해시로 변환.
|
||||
|
||||
2. **`javax.crypto.Cipher`**
|
||||
- **역할**: 대칭키(AES) 및 비대칭키(RSA) 암호화/복호화 작업을 수행.
|
||||
- **특징**: 운용 모드(예: CBC, GCM)와 패딩(예: PKCS5Padding)을 지정 가능.
|
||||
|
||||
3. **`java.security.KeyPairGenerator`**
|
||||
- **역할**: 비대칭키 알고리즘(RSA, DSA, EC 등)의 공개키와 개인키 쌍을 생성.
|
||||
- **특징**: 키 크기(예: 2048비트)를 지정하여 생성.
|
||||
|
||||
4. **`javax.crypto.KeyGenerator`**
|
||||
- **역할**: 대칭키 알고리즘(AES, DES 등)의 키를 생성.
|
||||
- **특징**: 고정된 길이의 무작위 키 생성.
|
||||
|
||||
5. **`javax.crypto.SecretKeyFactory`**
|
||||
- **역할**: 패스워드 기반 키 생성(PBKDF2) 또는 키 변환 작업을 수행.
|
||||
- **특징**: `SecretKey` 객체를 생성하거나 키 사양(KeySpec)을 변환.
|
||||
|
||||
6. **`java.security.SecureRandom`**
|
||||
- **역할**: 암호화에 적합한 고품질의 난수 생성.
|
||||
- **특징**: 일반 `Random`보다 안전성이 높음.
|
||||
|
||||
7. **`java.security.KeyStore`**
|
||||
- **역할**: 키와 인증서를 저장하고 관리하는 저장소.
|
||||
- **특징**: JKS, PKCS12 등 다양한 형식 지원.
|
||||
|
||||
---
|
||||
|
||||
### **각 클래스의 주요 메서드**
|
||||
#### **1. `MessageDigest`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `static getInstance(String algorithm)` | 지정된 해시 알고리즘(MD5, SHA-256 등)의 인스턴스를 생성. |
|
||||
| `update(byte[] input)` | 해시 계산에 사용할 입력 데이터를 추가. |
|
||||
| `digest()` | 입력 데이터를 해시로 변환하여 바이트 배열로 반환. |
|
||||
| `reset()` | 인스턴스를 초기 상태로 재설정. |
|
||||
|
||||
#### **2. `Cipher`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `static getInstance(String transformation)` | 암호화 알고리즘, 모드, 패딩(예: "AES/GCM/NoPadding")을 지정하여 인스턴스 생성. |
|
||||
| `init(int opmode, Key key, AlgorithmParameterSpec params)` | 암호화(ENCRYPT_MODE) 또는 복호화(DECRYPT_MODE) 모드로 초기화. 매개변수(IV 등) 지정 가능. |
|
||||
| `update(byte[] input)` | 암호화/복호화할 데이터를 추가(스트리밍 처리 시 사용). |
|
||||
| `doFinal(byte[] input)` | 암호화/복호화를 완료하고 결과를 반환. |
|
||||
| `updateAAD(byte[] aad)` | GCM 모드 등에서 인증용 추가 데이터(AAD)를 추가. |
|
||||
|
||||
#### **3. `KeyPairGenerator`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `static getInstance(String algorithm)` | 키 쌍 생성기 인스턴스를 반환(예: "RSA", "EC"). |
|
||||
| `initialize(int keysize)` | 키 크기(예: 2048비트)를 지정하여 초기화. |
|
||||
| `generateKeyPair()` | 공개키와 개인키 쌍(`KeyPair`)을 생성하여 반환. |
|
||||
|
||||
#### **4. `KeyGenerator`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `static getInstance(String algorithm)` | 대칭키 생성기 인스턴스를 반환(예: "AES"). |
|
||||
| `init(int keysize)` | 키 길이(예: 256비트)를 지정하여 초기화. |
|
||||
| `generateKey()` | 지정된 길이의 대칭키(`SecretKey`)를 생성하여 반환. |
|
||||
|
||||
#### **5. `SecretKeyFactory`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `static getInstance(String algorithm)` | 키 팩토리 인스턴스를 반환(예: "PBKDF2WithHmacSHA256"). |
|
||||
| `generateSecret(KeySpec spec)` | 키 사양(예: `PBEKeySpec`)을 기반으로 `SecretKey`를 생성. |
|
||||
| `getKeySpec(SecretKey key, Class keySpec)` | 주어진 키를 특정 사양(예: `PBEKeySpec`)으로 변환. |
|
||||
|
||||
#### **6. `SecureRandom`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `SecureRandom()` | 기본 알고리즘으로 안전한 난수 생성기 인스턴스를 생성. |
|
||||
| `nextBytes(byte[] bytes)` | 지정된 바이트 배열을 무작위 값으로 채움(예: IV, 솔트 생성에 사용). |
|
||||
| `setSeed(byte[] seed)` | 난수 생성기의 시드 값을 설정(보안상 권장되지 않음). |
|
||||
|
||||
#### **7. `KeyStore`**
|
||||
| **메서드** | **설명** |
|
||||
|---------------------------|--------------------------------------------------------------------------|
|
||||
| `static getInstance(String type)` | 키 저장소 인스턴스를 반환(예: "JKS", "PKCS12"). |
|
||||
| `load(InputStream stream, char[] password)` | 지정된 스트림에서 키 저장소를 로드하며, 비밀번호로 보호. |
|
||||
| `getKey(String alias, char[] password)` | 지정된 별칭에 해당하는 키를 반환. |
|
||||
| `setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)` | 키와 인증서를 저장소에 추가. |
|
||||
| `store(OutputStream stream, char[] password)` | 키 저장소를 지정된 스트림에 저장. |
|
||||
|
||||
---
|
||||
|
||||
### **클래스 간 연계 예제**
|
||||
아래는 `MessageDigest`, `Cipher`, `KeyGenerator`, `SecureRandom`을 함께 사용하는 AES-GCM 암호화 예제입니다.
|
||||
|
||||
```java
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
public class SecurityExample {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 1. 키 생성 (KeyGenerator)
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
|
||||
keyGen.init(256);
|
||||
SecretKey key = keyGen.generateKey();
|
||||
|
||||
// 2. IV 생성 (SecureRandom)
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] iv = new byte[12];
|
||||
random.nextBytes(iv);
|
||||
|
||||
// 3. 암호화 (Cipher)
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
|
||||
byte[] plaintext = "Hello, Java Security!".getBytes();
|
||||
byte[] ciphertext = cipher.doFinal(plaintext);
|
||||
|
||||
// 4. 해시 생성 (MessageDigest)
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] hash = digest.digest(plaintext);
|
||||
|
||||
// 출력
|
||||
System.out.println("Ciphertext: " + Base64.getEncoder().encodeToString(ciphertext));
|
||||
System.out.println("Hash: " + Base64.getEncoder().encodeToString(hash));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **추가 참고**
|
||||
- **제공자(Provider)**: `Security.getProviders()`로 사용 가능한 제공자를 확인할 수 있으며, 기본 제공자는 SunJCE입니다. Bouncy Castle 같은 외부 제공자를 추가할 수도 있습니다.
|
||||
- **확장성**: JCA는 플러그인 구조로 설계되어 새로운 알고리즘을 쉽게 추가 가능.
|
||||
|
||||
각 클래스에 대해 더 깊은 설명이나 특정 메서드의 사용 예제가 필요하면 말씀해주세요!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
사용자가 "Bouncy Castle"에 대해 물었을 때, 문맥상 자바 보안과 암호화에 관련된 질문을 이어오셨으므로, 여기서는 **Bouncy Castle 암호화 라이브러리**(The Bouncy Castle Cryptography Library)에 대해 설명하겠습니다. 만약 실제 "바운시 캐슬"(어린이 놀이기구)을 의미한 것이라면, 말씀해 주시면 그에 맞춰 수정하겠습니다!
|
||||
|
||||
---
|
||||
|
||||
### **Bouncy Castle 암호화 라이브러리란?**
|
||||
Bouncy Castle은 자바(Java)와 C#(.NET)용으로 개발된 오픈소스 암호화 라이브러리로, 다양한 암호화 알고리즘과 보안 프로토콜을 구현할 수 있는 강력한 도구입니다. 이 라이브러리는 **Legion of the Bouncy Castle Inc.**라는 호주 기반의 등록된 자선 단체에서 개발 및 유지보수하며, 2000년 5월에 처음 출시되었습니다.
|
||||
|
||||
Bouncy Castle은 자바의 기본 JCE(Java Cryptography Extension)와 JCA(Java Cryptography Architecture)를 보완하거나 대체할 수 있으며, 경량 API와 JCE 제공자(Provider)라는 두 가지 주요 구성 요소로 설계되었습니다. 이를 통해 메모리 제약이 있는 환경(예: Java ME)부터 일반 JVM 환경까지 폭넓게 사용할 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
### **주요 특징**
|
||||
1. **광범위한 알고리즘 지원**:
|
||||
- 대칭키 암호화: AES, DES, Blowfish 등.
|
||||
- 비대칭키 암호화: RSA, ECDSA, Diffie-Hellman 등.
|
||||
- 해시 함수: SHA-1, SHA-256, SHA-3 등.
|
||||
- 인증 암호화: AES-GCM, CCM 등.
|
||||
- 기타: OpenPGP, CMS, TLS/DTLS, X.509 인증서 생성 등.
|
||||
|
||||
2. **경량 API와 JCE 제공자**:
|
||||
- **경량 API**: 메모리 제약 환경에서 직접 사용할 수 있는 저수준 API.
|
||||
- **JCE 제공자**: 자바의 표준 암호화 프레임워크와 통합 가능.
|
||||
|
||||
3. **FIPS 인증**:
|
||||
- Bouncy Castle은 FIPS 140-2 인증 버전을 제공하며, 높은 보안 요구 사항이 있는 환경에서도 사용 가능.
|
||||
|
||||
4. **오픈소스 및 커뮤니티 지원**:
|
||||
- MIT 기반 라이선스로 배포되며, 누구나 무료로 사용 가능.
|
||||
- GitHub를 통해 소스 코드가 공개되고, 커뮤니티 피드백을 반영.
|
||||
|
||||
5. **플랫폼 유연성**:
|
||||
- Java뿐만 아니라 C#도 지원하며, Android 환경에서는 **Spongy Castle**이라는 변형 버전으로 사용됨.
|
||||
|
||||
---
|
||||
|
||||
### **Bouncy Castle의 기원**
|
||||
Bouncy Castle은 두 명의 자바 개발자가 서버 측 애플리케이션에서 반복적으로 암호화 라이브러리를 작성해야 하는 상황에 지쳤을 때 시작되었습니다. 이들은 Java ME(J2ME)와 같은 제한된 환경에서도 동작할 수 있는 유연한 라이브러리를 목표로 설계했으며, 이는 현재의 아키텍처로 이어졌습니다. 초기 버전은 약 27,000줄의 코드로 시작했지만, 현재(최신 버전 기준) 약 39만 줄 이상으로 확장되었습니다.
|
||||
|
||||
---
|
||||
|
||||
### **주요 사용 사례**
|
||||
- **암호화 및 복호화**: AES, RSA 등을 사용한 데이터 보호.
|
||||
- **디지털 서명**: ECDSA, RSA 기반 서명 생성 및 검증.
|
||||
- **키 관리**: 키 쌍 생성, 패스워드 기반 키 생성(PBKDF2 등).
|
||||
- **프로토콜 구현**: TLS, OpenPGP, S/MIME 등 보안 프로토콜 지원.
|
||||
- **인증서 관리**: X.509 인증서 생성 및 처리.
|
||||
|
||||
---
|
||||
|
||||
### **자바에서 Bouncy Castle 사용 예제**
|
||||
Bouncy Castle을 자바 프로젝트에 추가하려면 Maven 의존성을 추가하고, JCE 제공자로 등록한 뒤 사용할 수 있습니다.
|
||||
|
||||
#### **Maven 의존성**
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>1.78</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### **제공자 등록 및 AES 암호화 예제**
|
||||
```java
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.Security;
|
||||
|
||||
public class BouncyCastleExample {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Bouncy Castle 제공자 등록
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
// 키와 데이터 준비
|
||||
byte[] keyBytes = "ThisIsASecretKey".getBytes();
|
||||
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
|
||||
String input = "Hello, Bouncy Castle!";
|
||||
|
||||
// 암호화
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
byte[] encrypted = cipher.doFinal(input.getBytes());
|
||||
|
||||
System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **장점**
|
||||
- **풍부한 기능**: JCE보다 더 많은 알고리즘과 프로토콜 지원.
|
||||
- **유연성**: 경량 API로 임베디드 시스템에서도 사용 가능.
|
||||
- **제한 없음**: 미국 암호화 수출 제한(JCE의 과거 제약)을 피할 수 있음.
|
||||
- **커뮤니티와 지속적인 업데이트**: 활발한 개발과 최신 보안 표준 반영.
|
||||
|
||||
### **단점**
|
||||
- **복잡성**: JCE보다 학습 곡선이 다소 높을 수 있음.
|
||||
- **성능**: 일부 경우 JCE의 네이티브 최적화(AES-NI 등)에 비해 느릴 수 있음.
|
||||
- **의존성 관리**: Android 등 특정 환경에서는 별도 변형(Spongy Castle) 필요.
|
||||
|
||||
---
|
||||
|
||||
### **JCE와의 비교**
|
||||
- **JCE**: 자바 표준 라이브러리로, 간단한 사용과 기본 기능에 적합. 하지만 과거 키 길이 제한(현재는 완화됨)과 지원 알고리즘의 한계가 있음.
|
||||
- **Bouncy Castle**: 더 많은 알고리즘과 프로토콜을 제공하며, FIPS 인증과 같은 고급 요구 사항을 충족. 그러나 추가 설정이 필요.
|
||||
|
||||
---
|
||||
|
||||
Bouncy Castle은 암호화가 필요한 개발자에게 강력한 도구로 자리 잡고 있으며, 특히 보안 요구 사항이 높은 프로젝트에서 유용합니다. 추가로 궁금한 점이나 특정 기능에 대한 깊은 설명이 필요하면 말씀해 주세요!
|
||||
Reference in New Issue
Block a user