loose
이로운 개발하기
loose
전체 방문자
오늘
어제
  • 전체 (206)
    • ☕ Java (25)
    • 📘 Effective Java (9)
    • 🍃 Spring (49)
    • 📖 ORM (9)
    • ☸️ Kubernetes (13)
    • 🐧 Linux (5)
    • 🐋 Docker (5)
    • 🛠️ CI & CD (6)
    • 🕸️ Web (6)
    • 🔗 Distributed System (3)
    • 📜 Js (10)
    • 📈 Database (11)
    • 🗂️ Etc (36)
    • 🧑 Chitchat (10)
    • 📒 문학 (9)
    • 👜 개인 공부 창고 (0)

공지사항

최근 글

최근 댓글

loose

이로운 개발하기

[Spring] PQC(Post-Quantum Cryptography)
🍃 Spring

[Spring] PQC(Post-Quantum Cryptography)

2026. 1. 20. 20:26

PQC의 필요성

PQC가 필요한 이유는 양자 컴퓨터가 RSA 알고리즘을 무력화시킬 수 있기 때문이다.

PQC는 양자 내성 암호(Post-Quantum Cryptography)의 약자다.

이전에 Qiskit을 이용해서 IBM의 양자 컴퓨터를 이용했을 때 당시에는 지식이 모자라 양자 컴퓨터로만 구현이 가능한 BB84 알고리즘만이 유일한 해결 방안이지 않을까 생각했다.

하지만 PQC라는 개념이 있었으니 역시 당시에는 지식 부족이었다.

그리고 양자 내성 암호는 양자 컴퓨터가 아니어도 충분히 구현할 수 있는 개념이다.

PQC란

차세대로 나올 JEP에서는 PQC를 포함하고 있지만 프로덕션 환경에서 이용하려면 아직은 한참 시기상조다.
그럼 이용을 못하는 것인가? 그건 또 아닌게 현재는 Bouncy Castle의 PQC를 사용하는 것은 가능하다.

Bouncy Castle의 PQC를 이용하기 전 PQC가 어떤 의미를 가지고 있는지 일단 대략 알아볼 예정이다.

앞으로의 설명이 어질어질할테니 일단 대충 흐린 눈 😵‍💫 으로 봐도 된다.

 

해당 라이브러리에서 대표적으로 사용하는 PQC는 대표적으로 CRYSTALS-Kyber와 CRYSTALS-Dilithium 알고리즘을 사용한다.
CRYSTALS는 Cryptographic Suite for Algebraic Lattices의 약자인데, 대수(代數)적 격자를 기반으로 한 암호 알고리즘들의 모음이다.

 

일단 핵심은 '격자 알고리즘'을 사용한다는 것이다.
'격자'는 우리가 일반적으로 아는 바둑판 형태처럼 격자 형태로 이루어진 모양을 말한다.

쉽게 말해서 바둑판 형태의 격자에서 특정 점 A로부터 B까지의 최단 거리를 구하는 알고리즘이 가장 쉬운 예제라고 볼 수 있다.

하지만 바둑판 격자는 2차원인데 이 격자를 300차원으로 늘리면 계산 해야하는 방식은 엄청나게 복잡해질 것이다.

그 특성을 이용하여 양자컴퓨터가 쉽게 분석할 수 없도록 구현한 것이 격자 알고리즘이다.

여기까진 그래도 개념이 쉬운 것 같다.

 

하지만 일반적인 격자도 충분히 차원을 늘려서 알고리즘을 만들 수는 있지만 여기서 PQC는 대수라는 개념이 들어간다.

 

'대수'는 수학적 구조들의 일반적인 성질을 연구하는 수학의 분야를 뜻한다.
쉽게 말하면 단순히 정수로 표현하는 것이 넘어서 대체하는 수(x, y와 같은 대체 문자)를 사용하는 수학을 말한다. 

대수적 격자 기반 알고리즘은 대수학 중에 추상 대수학(abstract algebra)을 접목시킨다.

추상대수학에서는 환, 체와 같은 개념이 있는데 그 중에서 '환(Ring)'이라는 개념이 일반 격자 알고리즘에 추가되는 것이라고 볼 수 있다.

환을 설명하기 위한 가장 쉬운 예시는 더하기와 곱하기가 가능한 숫자들의 모음을 말할 수 있다.
대표적으로 정수다. 정수와 정수를 곱해도 정수의 숫자 범위에 포함하기에 환이라고 불린다.
일반적 격자는 규칙에 의해 덧셈 규칙은 만들 수 있지만 곱셈 규칙까지 추가하여 '환'이라는 대수적 특징을 결합한 격자라고 보면 된다.

여기서 가장 중요한 점은 '곱셈 규칙'이 추가된다는 것이다.

곱셈 규칙을 만족하는 모든 원소로 이루어진 격자로 인해 알고리즘을 구현할 때 속도가 빨라진다는 점이 핵심이다.

다시 말해 대수적 격자는 대수적 규칙에 의해 정의된 공리에 의해 추출된 격자를 사용하는 것이 대수적 격자라고 볼 수 있다.

얘기가 돌고 돌았을 수 있지만 복잡한 격자를 만드는 것은 일반적 격자를 만드는 것에도 충분히 적용시킬 수 있지만 대수적 격자를 쓰는 이유는 복잡한 격자를 만들기 위해서는 아니고 연산을 빠르게 하기 위해서다. 

 

그리고 CRYSTALS-Kyber와 CRYSTALS-Dilithium라는 용어에서 뒤에 Kyber와 Dilithium은 각각 스타워즈, 스타트렉에 나오는 가상 원소이며 복제가 불가능하며 안전한 성질을 띈 원소를 말한다.

그냥 안전하다라는 의미를 붙인 것 그 이상 이하도 아니다.

Spring에서의 PQC 사용 방법

Kyber KeyPair 생성

public class KyberKeyPairGenerator {

    public static KeyPair generate() throws Exception {
        Security.addProvider(new BouncyCastlePQCProvider());

        KeyPairGenerator kpg =
                KeyPairGenerator.getInstance("Kyber", "BCPQC");

        // Kyber512 / Kyber768 / Kyber1024 중 선택
        kpg.initialize(512);

        return kpg.generateKeyPair();
    }
}

 

Encapsulation

public class KyberEncapsulation {

    public static void encapsulate(KeyPair keyPair) throws Exception {
        Security.addProvider(new BouncyCastlePQCProvider());

        KEMGenerator kemGen =
                KEMGenerator.getInstance("Kyber", "BCPQC");

        // AES용 공유 비밀 생성
        KEMGenerateSpec spec =
                new KEMGenerateSpec(keyPair.getPublic(), "AES");

        var kemResult = kemGen.generateEncapsulated(spec);

        SecretKey sharedSecret = kemResult.getKey();
        byte[] encapsulation = kemResult.getEncapsulation();

        System.out.println("Shared Secret: " + sharedSecret.getEncoded().length);
        System.out.println("Encapsulation: " + encapsulation.length);
    }
}

Decapsulation

public class KyberDecapsulation {

    public static SecretKey decapsulate(
            KeyPair keyPair,
            byte[] encapsulation
    ) throws Exception {

        Security.addProvider(new BouncyCastlePQCProvider());

        KEMExtractor extractor =
                KEMExtractor.getInstance("Kyber", "BCPQC");

        KEMExtractSpec spec =
                new KEMExtractSpec(keyPair.getPrivate(), encapsulation, "AES");

        return extractor.extractSecretKey(spec);
    }
}

 

Code In Service

@Service
public class KyberService {

    public KeyPair generateKeyPair() throws Exception {
        return KyberKeyPairGenerator.generate();
    }
}

'🍃 Spring' 카테고리의 다른 글

[Spring] 이중 트랜잭션으로 인한 PessimisticLockingFailureException  (0) 2025.05.26
[Spring Batch] 개인 정리  (0) 2025.02.14
[Spring] RFC 7232 - Conditional Requests로 비용 및 부하 최적화 하기  (0) 2025.01.21
[Spring] gRPC 사용법  (0) 2025.01.20
[Spring] Redis 연결 관리 및 성능 최적화  (0) 2025.01.06
    '🍃 Spring' 카테고리의 다른 글
    • [Spring] 이중 트랜잭션으로 인한 PessimisticLockingFailureException
    • [Spring Batch] 개인 정리
    • [Spring] RFC 7232 - Conditional Requests로 비용 및 부하 최적화 하기
    • [Spring] gRPC 사용법
    loose
    loose
    불만하는 사람은 90명, 해결하는 사람은 9명, 리드하는 사람은 1명 음악과 낭만을 좋아합니다.
    hELLO. 티스토리 스킨을 소개합니다.
    제일 위로

    티스토리툴바