01. 비대칭 키 암호 알고리즘
- 정의: 암호화를 위해 사용하는 키 != 복호화를 위해 사용하는 키
- 공개 키: 모두에게 공개 가능
- 비밀 키: 공개해서는 안됨
- 공개 키 암호화 방식: 공개 키를 활용해 암호화 하는 것, 공개 키로 암호화 하면 함께 생성된 비밀키로만 복호화 가능해짐
02. 비대칭 키 암호 알고리즘 사용 방법
(1) A가 데이터를 암호화해서 B에게 보내야한다고 가정
- 먼저 B가 자신의 공개 키를 A에게 전달
- B의 공개키를 받은 A가 A에서 B의 공개키를 이용해서 암호화하여 암호문을 만듬
- 만들어진 암호문을 B에게 전달
- 전달받은 A의 암호문을 B에서 자신의 비밀키를 이용해 복호화하여 데이터를 받음
- 공개 키는 누구에게나 공개 할 수 있기 때문에 인터넷 망을 이용하여 전달이 가능해짐
- 만들어진 암호문은내가 가진 비밀 키로만 복호화하여 평문을 얻을 수 있기 때문에 다른 사람은 풀 수 없음
- 이런 과정을 통해 공개키와 달리 사람이 공용으로 사용하는 인터넷 망에서 키를 도난당하지 않고 전달 가능함
(2) 반대로 보내려는 사람, 즉 A가 가지고 있는 비밀키로 암호화 하고 A의 공개 키로 복호화 하는 방법
- 이 방법은 전자 서명을 할 때 사용하는 방법
- A가 보낸 암호문은 A의 공개키로만 복호화가 가능하기 때문에, A가 문서를 암호화하여 보냈다는 것이 인증됨
03. 비대칭 키 암호 알고리즘을 JAVA로 구현하기
(1) 비대칭 키 암호 알고리즘 - 비대칭 키 생성하기
import javax.crypto.Cipher;
import java.security.*;
import java.util.Arrays;
import java.util.Base64;
public class RSAEncryption {
private PrivateKey privateKey = null;
private PublicKey publicKey = null;
public RSAEncryption(){
this.makeKey();
}
// 비대칭 키 생성 메서드
public KeyPair makeKey(){
KeyPairGenerator keyPairGenerator = null;
KeyPair keyPair = null;
try{
// 비대칭 키 생성을 위한 객체 생성
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
// RSA 알고리즘의 비트 수를 2048로 설정
keyPairGenerator.initialize(2048);
// 비대칭 키(공개 키, 비밀 키) 생성
keyPair = keyPairGenerator.generateKeyPair();
// 비밀 키 변수 할당
privateKey = keyPair.getPrivate();
// 공개 키 변수 할당
publicKey = keyPair.getPublic();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keyPair;
}
}
- 비대칭 키 암호 알고리즘을 사용하려면 공개키-비밀키를 만들어야 함
- KeypairGenerator와 Keypair을 이용하여 비대칭 키 생성을 위한 객체를 생성함
- KeypairGenerator의 알고리즘은 RSA로 불러오고, 비트 수를 2048로 설정함
- 그리고 keypair에 비대칭 키를 등록하고, 비밀키와 공개키에 생성된 값을 할당함
(2) 비대칭 키 암호 알고리즘 - 공개키로 암호화하기
// 암호화 함수
public String encrypt(String plainText) throws Exception {
byte[] cipherText = null;
// 암호화 객체 생성
Cipher cipher = Cipher.getInstance("RSA");
// 암호화 모드, 공개키를 입력하여 암호화 객체 초기화
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 데이터 암호화 수행
cipherText = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText = " + Arrays.toString(cipherText));
// Base64로 인코딩하여 암호문 반환
return Base64.getEncoder().encodeToString(cipherText);
}
- RSA: 전문가들이 권고하는 알고리즘, 알고리즘의 길이가 길기 때문에 보안적임
- 암호 알고리즘을 ENCRYT_MODE로 지정하고, 공개 키 변수 publicKey를 지정하여 암호화 객체를 초기화함
- 그리고 데이터 암호화를 위한 함수 doFinal()을 호출하여 암호화된 문장을 반환받음
- 리턴값으로 base64 형식으로 인코딩하여 반환함
(3) 비대칭 키 암호 알고리즘 - 비밀키로 복호화하기
// 복호화 함수
public String decrypt(String cipherText) throws Exception {
byte[] plainText = null;
// 암호화 객체 생성
Cipher cipher = Cipher.getInstance("RSA");
// 복호화 모드, 비밀키를 입력하여 암호화 객체 초기화
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 데이터 복호화 수행
plainText = cipher.doFinal(Base64.getDecoder().decode(cipherText));
// 바이트 형식으로 복호화된 데이터를 문자열 형식으로 변환하여 반환
return new String(plainText);
}
(4) 결과
더보기
plain Text2: 123456
encrypted2: VAnkcLJjOiLrhpC7Cgyf1Vng+RzEupJBPfTVUjIE5a/N5Z8mDz3r/6biUXnd05bRVRbSr0vF/Qx3iDFey0hHbzFy4hNRDdSDSmXJ3PoGAXgZh3cCbrPFTO1uamuuyb8LwWRZA8MWQyDbBNnhCdz8K1YiOinfialMvx5KExpT0eINVlhRca01tk7MelZeaReD4xe7raHWfzRNdOzdwIDoq9VVX94vsr7YJY1yr8N0kY66FT+iJzaEl4eMGoOZ7krfMqT5v5KpMOm7Rk9SmkRyGsfWnoqOQYLae8ZkTUBMk3UJDXoVsBihc59DbPtA7ns3W/vUcNLM6L7JqD5GJoLfOg==
decrypted2: 123456
- 실행 결과에서 plain Text2로 123456을 암호화 하면
- encryted2에서처럼 긴 암호문이 나오는 것을 확인 할 수 있음
- 이 encryted2를 다시 복호화를 진행하면 decryted2처럼 평문이 나오는 결과를 확인할 수 있음
(5) 번외 - 다른 쌍의 비밀키-공개키를 이용한 경우
- 암호화 한 공개키의 쌍인 비밀키가 아닌 다른 암호키의 비밀키를 사용하면 다음과 같은 BadPaddingException Error가 발생함
'JAVA 심화' 카테고리의 다른 글
[JAVA] 심화 - 단방향 암호화 기법 (2) (0) | 2024.12.30 |
---|---|
[JAVA] 심화 - 단방향 암호화 기법 (1) (0) | 2024.12.30 |
[JAVA] 심화 - 양방향 암호화 기법, 대칭 키 암호 알고리즘 (1) (1) | 2024.12.30 |