implementation "com.nimbusds:nimbus-jose-jwt:9.37.3"
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.RSADecrypter;
import com.nimbusds.jose.crypto.RSAEncrypter;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import java.nio.charset.StandardCharsets;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
public class RSAUtil {
// RSA 키 생성 (개인키, 공개키)
public static RSAKey generateRSAKey(String keyId) throws JOSEException {
return new RSAKeyGenerator(2048).keyID(keyId).generate();
}
// 공개키로 암호화
public static String encrypt(String message, RSAPublicKey publicKey) throws JOSEException {
JWEObject encryptObject = new JWEObject(
new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM),
new Payload(message.getBytes(StandardCharsets.UTF_8))
);
encryptObject.encrypt(new RSAEncrypter(publicKey));
return encryptObject.serialize();
}
// 개인키로 서명
public static String sign(String payload, RSAPrivateKey privateKey) throws JOSEException {
JWSObject signObject = new JWSObject(
new JWSHeader(JWSAlgorithm.RS256),
new Payload(payload)
);
signObject.sign(new RSASSASigner(privateKey));
return signObject.serialize();
}
// 공개키로 서명검증
public static String verifySignature(String signedToken, RSAPublicKey publicKey) throws Exception {
JWSObject signObject = JWSObject.parse(signedToken);
if (signObject.verify(new RSASSAVerifier(publicKey))) {
return signObject.getPayload().toString();
}else{
throw new RuntimeException("공개키 서명 검증 실패");
}
}
// 개인키로 복호화
public static String decrypt(String encryptedToken, RSAPrivateKey privateKey) throws Exception {
JWEObject encryptObject = JWEObject.parse(encryptedToken);
encryptObject.decrypt(new RSADecrypter(privateKey));
return encryptObject.getPayload().toString();
}
}
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
import com.nimbusds.jose.jwk.RSAKey;
public class RSADemo {
public static void main(String[] args) throws Exception {
String msg = "나는 오늘 백운포에 송원 왕갈비를 먹으러 간다 비밀이다!!";
// 0. A(송신자), B(수신자) RSA 키 생성
RSAKey aKey = RSAUtil.generateRSAKey("A");
RSAKey bKey = RSAUtil.generateRSAKey("B");
RSAKey cKey = RSAUtil.generateRSAKey("C");
// ===== 송신 과정 =====
// 1. 수신자(B)의 공개키로 암호화
String encrypted = RSAUtil.encrypt(msg, bKey.toRSAPublicKey());
System.out.println("1. 암호화: " + encrypted.substring(0, 50) + "...");
// 2. 송신자(A)의 개인키로 서명
String signed = RSAUtil.sign(encrypted, aKey.toRSAPrivateKey());
System.out.println("2. 서명: " + signed.substring(0, 50) + "...");
System.out.println();
// ===== 수신 과정 =====
// 3. 송신자(A)의 공개키로 서명 검증
String verify = RSAUtil.verifySignature(signed, aKey.toRSAPublicKey());
System.out.println("3. 서명 검증: " + verify);
// 4. 수신자(B)의 개인키로 복호화
String decrypted = RSAUtil.decrypt(verify, bKey.toRSAPrivateKey());
System.out.println("4. 복호화: " + decrypted);
}
}