[Java] RSA 암호화를 이용한 전자서명

gyu·2024년 5월 5일

전자서명이란?

디지털 형식의 데이터나 메시지에 대한 무결성과 발신자의 정체성을 증명하기 위해 사용되는 디지털 기술이다. 서명자가 해당 전자문서에 서명하였음을 나타내기 위해 전자문서에 첨부되거나 논리적으로 결합된 전자적 형태의 정보를 의미한다.

공개키 암호 방식

전자서명을 구현하는 기술로 공개키 암호 방식을 일반적으로 사용한다.
키 생성 알고리즘을 통해 한쌍의 개인키와 공개키를 생성하며, 생성된 개인키는 서명자가 관리하고 공개키는 서명 확인이 필요한 주체에 전달된다.
일반적으로 RSA 공개키 암호 방식, 미국연방표준 전자서명 알고리즘(DSA), 타원 곡선 전자서명 알고리즘(ECDSA)등이 있다.

전자서명 Java 예시 코드

  1. KeyPairGenerator를 이용하여 RSA 알고리즘을 기반으로 하는 공개키, 개인키 쌍을 생성한다. 이 쌍은 전자서명의 생성 및 검증에 사용된다.
  2. Signature 인스턴스를 "SHA256withRSA" 알고리즘으로 초기화한다. SHA-256의 해시를 계산하고 그 결과를 개인키로 암호화하여 서명을 생성한다.
  3. Signature 인스턴스를 공개키로 초기화한다.
  4. Signature의 verify() 메서드를 호출하여 서명이 유효한지 확인한다. 유효하면 true, 그렇지 않으면 false를 반환한다.
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SignatureTest {

    private final static int KEY_SIZE = 2048;

    public static void main(String[] args) {
        PublicKey publicKey = null;   // 공개키
        PrivateKey privateKey = null;  // 개인키
        String message = "전자서명 테스트"; // 전달 메시지

        try {
            // 공개키, 개인키 쌍을 생성
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(KEY_SIZE);
            KeyPair keyPair = keyGen.generateKeyPair();

            publicKey = keyPair.getPublic();
            privateKey = keyPair.getPrivate();

            // SHA256withRSA 알고리즘으로 Signature 초기화
            Signature signature = Signature.getInstance("SHA256withRSA");
            // 개인키로 암호화하여 서명 생성
            signature.initSign(privateKey);
            // 서명 데이터 업데이트
            signature.update(message.getBytes());
            // 전자서명 생성 후 Base64 인코딩
            String encodedSignature = Base64.getEncoder().encodeToString(signature.sign());

            // Signature를 공개키로 초기화
            signature.initVerify(publicKey);
            // 검증 대상 메시지 전달
            signature.update(message.getBytes());
            // 제공된 서명이 유효한지 확인
            boolean isVerified = signature.verify(Base64.getDecoder().decode(encodedSignature));
            log.info("전자서명 검증 결과: {}", isVerified);

        } catch (Exception e) {
            log.error("An error occurred while performing the electronic signature.", e);
        }
    }
}


0개의 댓글