자바 기반 Diffie-Hellman 키 교환 프로토콜과 대칭 암호화 연동 과정

Diffie-Hellman(DH) 알고리즘은 양방향 보안 통신을 위해 사전에 합의하지 않은 두 엔터티가 안전하지 않은 네트워크 환경을 통해 공유 비밀 키를 생성하는 핵심 기술입니다. 이 방식으로 도출된 시크릿 키는 일반적으로 효율적인 대칭 암호화 방식을 위한 입력값으로 사용되며, 현대적인 자바 애플리케이션에서는 JCA(Java Cryptography Architecture) 및 JCE(Java Cryptography Extension) API 를 통해 이를 구현할 수 있습니다.

1. 발신자 (Initiator) 측 키쌍 생성

통신의 시작점은 발신자 측에서 난수를 기반으로 한 비대칭 키쌍을 생성하는 것입니다. 이때 생성된 공개키는 상대방에게 전송되어 파라미터 추출용으로 활용되며, 비공개키는 안전하게 로컬에 보관되어야 합니다.

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
kpg.initialize(512); // DH 알고리즘에 적합한 키 길이 설정
KeyPair localKP = kpg.generateKeyPair();

// 전송용 인코딩된 공개키
byte[] outgoingPubKeyBytes = localKP.getPublic().getEncoded();

2. 수신자 (Responder) 측 키 쌍 및 파라미터 유도

수신자는 발신자로부터 받은 공개키 바이트 배열을 해독하여 해당 알고리즘의 매개변수(parameter spec)를 추출해야 합니다. 이를 통해 호환 가능한 자신의 키쌍을 생성하며, 이 과정에서 별도의 파라미터 전달 없이 공개키 내부 정보만으로 초기화가 가능합니다.

KeyFactory kf = KeyFactory.getInstance("DH");
X509EncodedKeySpec xSpec = new X509EncodedKeySpec(outgoingPubKeyBytes);
PublicKey remotePubKey = kf.generatePublic(xSpec);

// 원격지 공개키에서 DH 매개변수 추출
DHParameterSpec dhParams = ((DHPublicKey) remotePubKey).getParams();

KeyPairGenerator peerKpg = KeyPairGenerator.getInstance("DH");
peerKpg.initialize(dhParams);
KeyPair remoteKP = peerKpg.generateKeyPair();

// 응답용 인코딩된 공개키
byte[] responsePubKeyBytes = remoteKP.getPublic().getEncoded();

3. 공유 비밀 키 (Shared Secret) 파생

양측 모두 자신의 비공개키와 상대방의 공개키를 조합하여 동일한 시크릿 키를 산출합니다. 이 단계가 성공적으로 완료되면 양측은 동일한 대칭 키를 갖게 되며, 이를 위해 KeyAgreement 객체의 위상(phase) 처리를 수행합니다.

// 발신자 측 시크릿 키 생성 (수신자의 공개키 필요)
KeyAgreement kaLocal = KeyAgreement.getInstance("DH");
kaLocal.init(localKP.getPrivate());
kaLocal.doPhase(remotePubKey, true); 
SecretKey commonSymKeyLocal = kaLocal.generateSecret("AES");

// 수신자 측 시크릿 키 생성 (발신자의 공개키 필요)
KeyAgreement kaRemote = KeyAgreement.getInstance("DH");
kaRemote.init(remoteKP.getPrivate());
// 발신자의 원래 공개키를 다시 사용하거나 재구성해야 함
PublicKey initPubKey = kf.generatePublic(new X509EncodedKeySpec(outgoingPubKeyBytes));
kaRemote.doPhase(initPubKey, true);
SecretKey commonSymKeyRemote = kaRemote.generateSecret("AES");

4. 암호화 및 복호화 수행

도출된 대칭 키 (여기서는 보안 강화를 위해 AES 알고리즘 적용) 를 사용하여 실제 데이터 블록의 암호화와 복호화 작업을 진행합니다. 이는 DH 가 순수한 키 교환 도구임을 보여주기 위한 필수적인 후속 단계입니다.

// 발신자: 데이터 암호화
String message = "보안 전송 대상 텍스트";
Cipher encCipher = Cipher.getInstance("AES");
encCipher.init(Cipher.ENCRYPT_MODE, commonSymKeyLocal);
byte[] encryptedPayload = encCipher.doFinal(message.getBytes("UTF-8"));
System.out.println("암호화 결과: " + Hex.encodeHexString(encryptedPayload));

// 수신자: 데이터 복호화
Cipher decCipher = Cipher.getInstance("AES");
decCipher.init(Cipher.DECRYPT_MODE, commonSymKeyRemote);
byte[] decryptedPayload = decCipher.doFinal(encryptedPayload);
System.out.println("복호화 내용: " + new String(decryptedPayload, "UTF-8"));

태그: java JCE Diffie-Hellman KeyExchange AES

6월 6일 00:07에 게시됨