ECDHESA256 암호화 추가
This commit is contained in:
@@ -0,0 +1,112 @@
|
|||||||
|
package com.kjbank.encrypt.exchange.crypto;
|
||||||
|
|
||||||
|
import com.nimbusds.jose.*;
|
||||||
|
import com.nimbusds.jose.crypto.*;
|
||||||
|
import com.nimbusds.jose.jwk.*;
|
||||||
|
import com.nimbusds.jose.jwk.gen.*;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.security.interfaces.ECPublicKey;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
|
||||||
|
public class ECDHESA256Cipher {
|
||||||
|
|
||||||
|
private ECKey myECKey;
|
||||||
|
private ECKey receiverPublicJWK;
|
||||||
|
|
||||||
|
// 생성자: 수신자 키 쌍을 준비
|
||||||
|
public ECDHESA256Cipher() throws Exception {
|
||||||
|
this.myECKey = new ECKeyGenerator(Curve.P_256)
|
||||||
|
.keyUse(KeyUse.ENCRYPTION)
|
||||||
|
.keyID("receiver-key")
|
||||||
|
.generate();
|
||||||
|
|
||||||
|
this.receiverPublicJWK = myECKey.toPublicJWK();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//생성자: 내 키쌍 로드용 생성자 (복호화할 때 필요)
|
||||||
|
public ECDHESA256Cipher(String myKeystorePath, String storePass, String keyAlias, String keyPass) throws Exception {
|
||||||
|
KeyStore ks = KeyStore.getInstance("PKCS12");
|
||||||
|
ks.load(new FileInputStream(myKeystorePath), storePass.toCharArray());
|
||||||
|
|
||||||
|
PrivateKey myPrivateKey = (PrivateKey) ks.getKey(keyAlias, keyPass.toCharArray());
|
||||||
|
X509Certificate myCert = (X509Certificate) ks.getCertificate(keyAlias);
|
||||||
|
ECPublicKey myPublicKey = (ECPublicKey) myCert.getPublicKey();
|
||||||
|
|
||||||
|
this.myECKey = new ECKey.Builder(Curve.P_256, myPublicKey)
|
||||||
|
.privateKey(myPrivateKey)
|
||||||
|
.keyUse(KeyUse.ENCRYPTION)
|
||||||
|
//.keyID("my-key")
|
||||||
|
.keyID(myCert.getSerialNumber().toString()) // 인증서 시리얼번호를 keyID로 사용
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 생성자: 상대방 인증서에서 공개키 로드
|
||||||
|
public ECDHESA256Cipher(String certPath) throws Exception {
|
||||||
|
// 1. 인증서 로드
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
|
try (FileInputStream fis = new FileInputStream(certPath)) {
|
||||||
|
X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);
|
||||||
|
|
||||||
|
// 2. 공개키 추출
|
||||||
|
ECPublicKey publicKey = (ECPublicKey) cert.getPublicKey();
|
||||||
|
|
||||||
|
// 3. Nimbus ECKey로 변환
|
||||||
|
this.receiverPublicJWK = new ECKey.Builder(Curve.P_256, publicKey)
|
||||||
|
.keyUse(KeyUse.ENCRYPTION)
|
||||||
|
//.keyID("receiver-key")
|
||||||
|
.keyID(cert.getSerialNumber().toString()) // 인증서 시리얼번호를 keyID로 사용
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 암호화 메서드
|
||||||
|
public String encrypt(String jsonPayload) throws Exception {
|
||||||
|
if (receiverPublicJWK == null) {
|
||||||
|
throw new IllegalStateException("상대방 공개키가 초기화되지 않았습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
|
JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES_A256KW, EncryptionMethod.A256GCM)
|
||||||
|
.contentType("application/json")
|
||||||
|
.keyID(receiverPublicJWK.getKeyID())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
JWEObject jweObject = new JWEObject(header, new Payload(jsonPayload));
|
||||||
|
|
||||||
|
JWEEncrypter encrypter = new ECDHEncrypter(receiverPublicJWK);
|
||||||
|
jweObject.encrypt(encrypter);
|
||||||
|
|
||||||
|
return jweObject.serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 복호화 메서드(상대방이 나한테 보낸것)
|
||||||
|
public String decrypt(String jweString) throws Exception {
|
||||||
|
if (myECKey == null) {
|
||||||
|
throw new IllegalStateException("내 개인키가 초기화되지 않았습니다.");
|
||||||
|
}
|
||||||
|
JWEObject decryptedJWE = JWEObject.parse(jweString);
|
||||||
|
JWEDecrypter decrypter = new ECDHDecrypter(myECKey);
|
||||||
|
decryptedJWE.decrypt(decrypter);
|
||||||
|
|
||||||
|
return decryptedJWE.getPayload().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 상대방 공개키를 외부에 제공할 수 있도록 getter
|
||||||
|
public ECKey getReceiverPublicJWK() {
|
||||||
|
if (receiverPublicJWK == null) {
|
||||||
|
throw new IllegalStateException("상대방 공개키가 초기화되지 않았습니다.");
|
||||||
|
}
|
||||||
|
return receiverPublicJWK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 내 공개키를 상대방에게 제공할 수 있도록 getter
|
||||||
|
public ECKey getMyPublicJWK() {
|
||||||
|
if (myECKey == null) {
|
||||||
|
throw new IllegalStateException("내 키쌍이 초기화되지 않았습니다.");
|
||||||
|
}
|
||||||
|
return myECKey.toPublicJWK();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user