Encryption Algorithm

PGP (Pretty Good Privacy) 원리와 사용 예

임베디드 친구 2024. 12. 8. 11:44
반응형

PGP란?

PGP(Pretty Good Privacy)는 전자 통신에서 보안을 위해 사용되는 암호화 프로그램입니다. 데이터 암호화, 디지털 서명, 이메일 보안 등 다양한 용도로 사용되며, 공개 키 암호화와 대칭 키 암호화를 결합하여 높은 수준의 보안을 제공합니다. 이 포스팅에서는 PGP의 원리, 동작 방식, 사용 예를 설명하고, Java와 Linux C로 간단한 구현 예제를 함께 제공합니다.

PGP의 기본 원리

PGP는 대칭 키 암호화와 공개 키 암호화를 혼합한 하이브리드 암호화 방식을 사용합니다. 기본적인 원리는 다음과 같습니다.

  1. 대칭 키 암호화: PGP는 먼저 대칭 키를 생성합니다. 이 대칭 키는 메시지를 암호화하는 데 사용되며, 암호화의 속도를 높입니다.
  2. 공개 키 암호화: 생성된 대칭 키는 수신자의 공개 키로 암호화되어 전송됩니다. 수신자만이 자신의 비밀 키로 이 대칭 키를 복호화할 수 있습니다.
  3. 디지털 서명: 발신자는 메시지에 자신의 개인 키로 디지털 서명을 생성하여 메시지의 무결성과 발신자의 신원을 보장합니다. 수신자는 발신자의 공개 키로 서명을 검증할 수 있습니다.

이러한 하이브리드 방식은 대칭 암호화의 속도와 공개 키 암호화의 보안성을 모두 제공하여 효율적이고 안전한 데이터 전송을 가능하게 합니다.

PGP의 주요 동작 방식

1. 데이터 암호화 및 전송

  • 발신자는 메시지를 대칭 키를 사용하여 암호화합니다.
  • 생성된 대칭 키는 수신자의 공개 키로 암호화됩니다.
  • 암호화된 메시지와 대칭 키가 수신자에게 전송됩니다.

2. 수신자의 데이터 복호화

  • 수신자는 자신의 비밀 키를 사용하여 암호화된 대칭 키를 복호화합니다.
  • 복호화된 대칭 키를 사용하여 원래의 메시지를 복원합니다.

3. 디지털 서명 검증

  • 발신자는 메시지에 해시 함수를 적용한 후, 자신의 개인 키로 해시 값을 암호화하여 디지털 서명을 생성합니다.
  • 수신자는 발신자의 공개 키로 이 서명을 검증하여 메시지가 변조되지 않았음을 확인할 수 있습니다.

PGP의 사용 예

PGP는 주로 이메일 암호화와 파일 보호를 위해 사용됩니다. 이메일의 본문과 첨부 파일을 암호화하여 수신자 이외의 누군가가 내용을 읽을 수 없도록 보호하며, 디지털 서명을 통해 발신자를 검증합니다.

PGP는 또한 파일이나 디렉터리의 무결성을 확인하는 데 사용됩니다. 중요한 파일에 디지털 서명을 적용하여, 해당 파일이 변조되지 않았는지 확인할 수 있습니다.

Java로 PGP 구현 예제

다음은 Java를 사용하여 간단한 PGP 스타일 암호화를 구현한 예제 코드입니다. 이 코드는 메시지를 공개 키로 암호화하고, 비밀 키로 복호화하는 과정의 일부를 보여줍니다.

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

public class PGPExample {
    public static void main(String[] args) throws Exception {
        // 공개 키/비밀 키 쌍 생성
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(2048);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 대칭 키 생성
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey symmetricKey = keyGen.generateKey();

        // 대칭 키를 공개 키로 암호화
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedSymmetricKey = cipher.doFinal(symmetricKey.getEncoded());

        System.out.println("암호화된 대칭 키: " + new String(encryptedSymmetricKey));

        // 대칭 키를 비밀 키로 복호화
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedSymmetricKey = cipher.doFinal(encryptedSymmetricKey);

        System.out.println("복호화된 대칭 키: " + new String(decryptedSymmetricKey));
    }
}

이 예제에서는 RSA 알고리즘을 사용하여 공개 키와 비밀 키를 생성하고, 대칭 키(AES)를 암호화 및 복호화하는 과정을 보여줍니다. 실제 PGP 구현에서는 대칭 키를 이용해 메시지를 암호화하고, 서명을 추가하여 보안을 강화합니다.

Linux C로 PGP 구현 예제

다음은 Linux C 환경에서 OpenSSL 라이브러리를 사용하여 PGP 스타일 암호화를 구현한 간단한 예제입니다.

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>

int main() {
    int ret;
    RSA *rsa = NULL;
    BIGNUM *bne = NULL;
    unsigned char *encrypted = NULL;
    unsigned char *decrypted = NULL;
    int encrypted_length, decrypted_length;
    const char *message = "Hello, PGP!";

    // 공개 키/비밀 키 쌍 생성
    bne = BN_new();
    ret = BN_set_word(bne, RSA_F4);
    rsa = RSA_new();
    ret = RSA_generate_key_ex(rsa, 2048, bne, NULL);

    // 메시지를 암호화
    encrypted = (unsigned char *)malloc(RSA_size(rsa));
    encrypted_length = RSA_public_encrypt(strlen(message) + 1, (unsigned char*)message, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
    if (encrypted_length == -1) {
        ERR_print_errors_fp(stderr);
        return 1;
    }
    printf("암호화된 메시지: %s\n", encrypted);

    // 메시지를 복호화
    decrypted = (unsigned char *)malloc(RSA_size(rsa));
    decrypted_length = RSA_private_decrypt(encrypted_length, encrypted, decrypted, rsa, RSA_PKCS1_OAEP_PADDING);
    if (decrypted_length == -1) {
        ERR_print_errors_fp(stderr);
        return 1;
    }
    printf("복호화된 메시지: %s\n", decrypted);

    // 메모리 해제
    RSA_free(rsa);
    BN_free(bne);
    free(encrypted);
    free(decrypted);

    return 0;
}

이 코드는 OpenSSL을 사용하여 RSA 공개 키 암호화를 수행합니다. 메시지를 공개 키로 암호화하고, 비밀 키로 복호화하는 과정을 보여주며, PGP의 기본적인 암호화와 유사한 작업을 수행합니다.

결론

PGP는 대칭 키 암호화와 공개 키 암호화를 결합하여 보안을 제공하는 강력한 암호화 프로토콜입니다. 이메일 보안, 파일 보호 등 다양한 분야에서 사용되며, 메시지의 기밀성, 무결성, 인증을 보장합니다. 이번 포스팅에서는 PGP의 기본 원리와 동작 방식을 설명하고, Java와 Linux C를 이용한 간단한 구현 예제를 통해 PGP의 작동 방식을 살펴보았습니다.

PGP를 사용하여 데이터 보호의 중요성을 체험해 보시기 바랍니다.

반응형