Rust

[PKI 예제] RSA로 서명하고 검증하기

comnic 2023. 12. 12. 07:50
반응형

RSA로 서명하고 검증하기

RSA를 사용하여 기본적인 PKI(Public Key Infrastructure)를 구현해 보겠습니다. 이 예제에서는 다음의 단계를 따라갑니다.

  1. 키 생성: RSA 알고리즘을 사용하여 공개키와 개인키를 생성합니다.
  2. 서명: 개인키를 사용하여 메시지에 서명을 생성합니다.
  3. 검증: 공개키를 사용하여 서명이 유효한지 검증합니다.

먼저, rsa 라이브러리를 사용하여 RSA 알고리즘을 구현합니다. 이 라이브러리는 RSA 키 생성, 서명, 검증 등을 편리하게 다룰 수 있도록 도와줍니다.

먼저 [rsa, num-bigint]를 dependencies에 추가합니다.

# Cargo.toml에 의존성 추가
[dependencies]
rsa = "0.3.0"
num-bigint = "0.4.0"

혹은 cargo-edit를 사용해 추가할 수도 있습니다.

다음은 RSA를 사용한 PKI 구현의 예제 코드입니다:

use rsa::{RSAPrivateKey, RSAPublicKey, PaddingScheme};
use num_bigint::BigUint;
use rand::rngs::OsRng;

fn main() {
    // 1. 키 생성
    let private_key = RSAPrivateKey::new(&mut OsRng, 2048).expect("Failed to generate a private key");
    let public_key = RSAPublicKey::from(&private_key);

    // 2. 서명 생성
    let message = "Hello, PKI!";
    let signature = sign(message.as_bytes(), &private_key);

    // 3. 검증
    let is_valid = verify(message.as_bytes(), &signature, &public_key);

    // 결과 출력
    if is_valid {
        println!("Signature is valid.");
    } else {
        println!("Signature is not valid.");
    }
}

// 서명 생성 함수
fn sign(message: &[u8], private_key: &RSAPrivateKey) -> Vec<u8> {
    // 서명 생성을 위해 rsa::Signer를 사용
    let mut signer = rsa::Signer::new(rsa::PKCS1_PSS_SHA256, &private_key).expect("Failed to create signer");
    
    // 메시지 업데이트
    signer.update(message);
    
    // 최종 서명 반환
    signer.finalize().expect("Failed to finalize signature").to_vec()
}

// 검증 함수
fn verify(message: &[u8], signature: &[u8], public_key: &RSAPublicKey) -> bool {
    // 검증을 위해 rsa::Verifier를 사용
    let mut verifier = rsa::Verifier::new(rsa::PKCS1_PSS_SHA256, &public_key).expect("Failed to create verifier");
    
    // 메시지 업데이트
    verifier.update(message);
    
    // 서명 검증 후 결과 반환
    verifier.verify(signature)
}

상세 설명:

  1. 키 생성:
    • RSAPrivateKey::new: rsa 라이브러리를 사용하여 2048비트의 RSA 개인키를 생성합니다. 안전한 난수 생성기인 OsRng를 사용합니다.
    • RSAPublicKey::from: 개인키로부터 공개키를 생성합니다. 공개키는 RSA 개인키의 일부로 구할 수 있습니다.
  2. 서명 생성:
    • sign 함수: 개인키를 사용하여 메시지에 대한 서명을 생성합니다.
      • rsa::Signer::new: RSA 서명 생성기를 초기화합니다. PSS 패딩과 SHA-256 해시 알고리즘을 사용합니다.
      • signer.update: 서명 생성기에 메시지를 업데이트합니다.
      • signer.finalize: 서명 생성을 완료하고 결과를 벡터로 반환합니다.
  3. 검증:
    • verify 함수: 공개키를 사용하여 서명의 유효성을 검증합니다.
      • rsa::Verifier::new: RSA 서명 검증기를 초기화합니다. PSS 패딩과 SHA-256 해시 알고리즘을 사용합니다.
      • verifier.update: 검증기에 메시지를 업데이트합니다.
      • verifier.verify: 서명의 유효성을 검증하고 결과를 반환합니다.
  4. 결과 출력:
    • is_valid: 검증 결과를 통해 서명이 유효한지 확인합니다.

이 코드에서 rsa::PKCS1_PSS_SHA256는 서명 및 검증에 사용되는 패딩 및 해시 알고리즘을 나타냅니다. 이 예제에서는 SHA-256 해시와 PSS 패딩을 사용하였습니다.

위 코드는 단순한 예제일 뿐이며, 실제 환경에서는 키 저장, 키 관리, 서명 범위 및 기간, 인증서 발급 등의 다양한 측면을 고려해야 합니다. PKI 구현은 보안에 매우 민감하며, 가능한 한 신뢰할 수 있는 라이브러리 및 프레임워크를 사용하는 것이 좋습니다.

반응형