공지사항

GroSaaS & Tech

[GroSaaS 개발일지] 처음 보는 Agent를 어떻게 믿을까? 등록용 키부터 인증서 서명까지

Raoul16 2026. 10. 26. 12:52

 

[GroSaaS 개발일지] 처음 보는 Agent를 어떻게 믿을까? 등록용 키부터 인증서 서명까지

안녕하세요,

그로메트릭 입니다. 🐸

GroSaaS는 여러 보안 장비에서 발생하는 로그를 수집하고 분석하는 서비스입니다. 로그를 안전하게 모으려면 저장과 분석뿐 아니라, “지금 데이터를 보내는 Agent가 우리가 등록한 Agent가 맞는가?”도 확인해야 합니다.

이번 개발일지에서는 등록용 키를 이용한 최초 인증부터 CSR(Certificate Signing Request)과 CA(인증기관)의 전자서명까지, Agent의 신원을 신뢰하는 과정을 살펴봅니다. 발급된 인증서가 TLS와 mTLS 통신에서 어떤 역할을 하는지도 함께 알아보겠습니다.


Agent는 처음 연결할 때 어떻게 신원을 증명할까? 🔍

보안 장비의 로그를 수집하는 시스템에서는 각 Agent를 구분할 수 있어야 합니다. 이를 위해 관리 서버는 등록된 Agent에 고유한 식별 정보를 부여합니다.

하지만 식별 정보와 인증 수단은 다릅니다. 식별자는 Agent를 구별하기 위한 값이지, 그 자체로 해당 Agent의 신원을 증명하지는 않습니다. 식별자만으로 접속을 허용하면 다른 프로그램이 등록된 Agent를 사칭할 수 있습니다.

이를 위해 최초 연결에는 별도의 비밀값인 등록용 키를 사용하고, 이후에는 인증서로 신원을 확인하는 구조를 설계했습니다. 핵심은 단순히 키를 만드는 것이 아니라 누가 무엇에 서명하고, 상대방이 그 서명을 어떻게 검증하는가에 있습니다.
​

등록용 키: 최초 연결에 사용하는 임시 열쇠 🔑

초기 등록은 새 Agent가 서비스에 처음 등록되고 신뢰를 얻는 과정입니다. 이를 위한 등록용 키는 영구 비밀번호가 아니라 최초 인증을 위한 임시 자격 증명입니다.

등록용 키를 발급하고 확인하는 흐름은 다음과 같습니다.

① 관리자가 로그 수집 대상 장비를 등록합니다.
② 관리 서버가 Agent 식별 정보와 최초 인증에 사용할 등록용 키를 생성합니다.
③ 관리자는 발급받은 키를 로컬 Agent에 입력합니다.
④ Agent가 키를 등록 서버에 전달하면 서버는 키의 유효성을 검증하고 필요한 장비 정보를 반환합니다. 이 단계의 조회만으로는 키를 소모하지 않습니다.

agent 최초 등록 흐름도

 

등록용 키의 인증 비밀값은 암호학적으로 안전한 난수 생성기를 통해 예측하기 어렵게 생성합니다. 키를 확인하는 데 필요한 식별 정보와 인증용 비밀값도 서로 구분해 관리합니다.

 

보안상 중요한 점은 비밀값을 데이터베이스에 원문으로 저장하지 않는다는 것입니다. 서버는 별도로 관리하는 Pepper와 HMAC-SHA256을 이용해 검증값을 생성하고 저장합니다. 이후 등록용 키를 검증할 때는 전달받은 비밀값으로 검증값을 다시 계산해 비교합니다.

 

등록용 키는 사용 가능한 기간을 제한하고, 원문을 최초 발급 단계에서만 확인할 수 있게 해야 합니다. 이후 일반 조회 결과나 로그에 비밀값을 남기지 않는 것도 중요합니다.

 

여기서 사용하는 HMAC-SHA256은 서버가 등록용 키의 비밀값을 검증하기 위한 MAC(Message Authentication Code) 방식입니다. 뒤에서 살펴볼 CSR과 인증서의 공개키 기반 전자서명과는 목적과 키 구조가 다릅니다. 등록용 키는 최초 인증 자격을 확인하고, 인증서 서명은 신뢰할 수 있는 발급자가 공개키와 신원 정보를 연결하는 데 사용됩니다.

 

CSR과 인증서 서명: 누가 무엇에 서명할까?✍️

등록용 키가 최초 접속 권한을 확인하는 임시 열쇠라면, 인증서는 이후 통신에서 사용할 신원 확인 수단입니다. 그 둘을 이어 주는 절차가 CSR 제출과 인증서 서명입니다. 이 과정에는 서로 다른 주체가 수행하는 두 번의 전자서명이 등장합니다.

CSR은 Agent가 “이 공개키를 사용하는 주체에게 인증서를 발급해 달라”고 요청하는 데이터입니다. Agent는 자신의 환경에서 개인키와 공개키 한 쌍을 생성하고, 공개키와 신청 정보를 담은 CSR을 개인키로 서명합니다. 개인키 자체는 서버에 전송하지 않습니다.

• 개인키(Private Key): Agent 내부에서 보관해야 하는 비밀키
• 공개키(Public Key): 인증서에 포함되어 다른 시스템과 공유할 수 있는 키
• CSR: 공개키와 신청 정보 등을 담고, 대응하는 개인키로 서명한 인증서 발급 요청

첫 번째 서명: Agent가 CSR에 서명합니다.

Agent가 CSR을 개인키로 서명하면, 등록 서버는 CSR 안의 공개키로 그 서명을 검증할 수 있습니다. 즉, 제출된 CSR이 해당 공개키와 짝을 이루는 개인키로 서명되었는지 확인하는 것입니다. 이를 공개키에 대한 소유 증명(Proof of Possession, PoP)이라고 합니다. 다만 CSR 서명만으로 요청자가 실제 등록된 Agent인지까지 알 수는 없습니다. 따라서 최초 등록 단계의 등록용 키 검증과 서버에 저장된 Agent 정보 확인이 별도로 필요합니다.

 

OpenSSL 예시: 개인키 생성과 CSR 서명 확인

CSR 자체 서명 검증 성공은 개인키 소유의 증거이지 실제 신원 인증은 아닙니다.

두 번째 서명: CA가 인증서에 서명합니다.

 

서버는 CSR의 유효성과 요청자의 등록 자격을 확인한 뒤, 서버가 신뢰하는 Agent 정보에 따라 인증서 내용을 구성합니다. CA(Certificate Authority)는 자신의 개인키로 인증서의 서명 대상 데이터에 전자서명합니다. 여기서 CA가 서명하는 대상은 ‘Agent의 개인키’나 ‘CSR 원문’이 아니라, Agent 공개키, 발급자, 신원, 유효기간, 용도 등을 담은 인증서 데이터입니다. 따라서 CSR에 적힌 신원 정보를 그대로 신뢰하기보다 서버 등록정보와 대조해 신원 필드를 결정하는 것이 중요합니다.

 

인증서를 받은 쪽은 신뢰하는 CA 또는 인증서 체인의 공개키로 서명을 검증합니다. 발급자 신뢰, 유효기간, 사용 목적, 대상 신원, 폐기 여부 등도 별도로 확인해야 합니다. 서명이 유효하다는 사실 하나만으로 모든 인증 조건을 충족하는 것은 아닙니다.

 

 

Certificate Signing Request - 클라이언트 인증서까지 발급 흐름도

 

OpenSSL 예시: 시험용 CA 서명과 인증서 확인

결과가 device.crt: OK이면 실습용 CA 기준 서명 검증이 성공한 것입니다.

인증서 발급 구조를 순서대로 정리하면 다음과 같습니다.

 

① Agent가 로컬에서 공개키와 개인키를 생성하고, 개인키로 CSR에 서명합니다.

② Agent가 등록용 키와 CSR을 서버에 제출합니다.

③ 등록 서버가 키의 유효성과 CSR의 서명을 확인하고, 공개키에 대응하는 개인키의 소유 여부를 검증합니다.

④ 서버 등록정보를 기준으로 인증서 신원을 구성하고, CA가 자신의 개인키로 인증서에 서명합니다.

⑤ Agent는 발급된 인증서를 수신해 로컬 개인키와 함께 보관합니다. 최초 인증용 등록용 키는 인증서 발급이 성공한 뒤 소모하도록 설계했습니다.

 

클라이언트 인증서에는 신원을 구분할 CN(Common Name), 클라이언트 인증 용도를 나타내는 EKU(clientAuth), 인증기관이 아님을 나타내는 CA:false 등의 제약을 둘 수 있습니다. 이런 조건은 인증서를 허용된 목적에 맞게 사용하는 데 도움을 줍니다.

 

인증서 서명이 안전한 통신으로 이어지는 방법도 간단히 살펴보겠습니다. TLS(Transport Layer Security)는 통신 상대의 인증서 등을 검증하고 안전한 세션 키를 협상해 전송 데이터를 암호화하는 프로토콜입니다. 일반적인 서버 인증 TLS에서는 클라이언트가 서버 인증서를 검증하며, mTLS(mutual TLS)에서는 서버와 클라이언트가 서로 인증서를 제시하고 검증합니다. 이 구조를 Agent 인증에 적용하면 서버도 로그를 보내는 Agent의 신원을 확인할 수 있습니다. 인증서는 신뢰할 주체를 확인하는 데 쓰이고, 실제 데이터 암호화는 TLS 연결에서 합의한 세션 키를 사용한다는 점이 핵심입니다.

 

여기서 중요한 점은 Agent가 정상 실행되는 것과 서버가 Agent의 신원을 인증하는 것은 다르다는 사실입니다. 등록용 키 검증, CSR 서명 확인, 인증서 발급, mTLS 연결은 각각 별도의 신뢰 단계입니다. 어느 한 단계의 성공이 전체 인증 과정의 성공을 뜻하지는 않습니다.

인증서 발급 도중 연결이 끊어지면 어떻게 될까?

여기서 중요한 질문은 최초 등록용 키를 언제 소모할 것인가입니다. 일반적인 키 확인 단계에서는 유효성만 검증하고, 인증서가 정상적으로 발급되었을 때 키를 소모하도록 설계할 수 있습니다. 다만 CA가 인증서를 서명한 직후 네트워크 연결이 끊어지면 서버는 발급을 마쳤지만 Agent는 결과를 받지 못할 수 있습니다.

 

따라서 ‘실패하면 같은 등록용 키로 다시 요청한다’는 규칙만으로는 부족합니다. 서버가 같은 CSR의 반복 요청을 어떻게 구분할지, 인증서 발급 이력과 등록용 키의 소모 상태를 어떻게 일관되게 기록할지, 응답이 유실된 경우 기존 결과를 재전달할지 등을 정해야 합니다. 중요한 것은 재시도하더라도 인증서 발급 이력과 Key 상태가 서로 어긋나지 않도록 만드는 것입니다.

 

CSR의 서명이 유효하다는 사실은 CSR에 담긴 공개키에 대응하는 개인키의 소유를 보여줄 뿐, 신청서에 적힌 이름과 조직까지 사실임을 증명하지는 않습니다. 따라서 등록 서버는 사전에 확인한 등록 정보와 CSR을 대조하고, 검증된 신원만 인증서에 반영해야 합니다.

CA의 개인키와 Agent의 개인키를 안전하게 보관하는 것도 중요합니다. Root CA의 키를 별도로 보호하고 중간 CA로 실제 인증서를 발급하는 방식은 피해 범위를 줄이는 데 도움이 됩니다. 또한 등록된 장비 정보가 삭제되더라도 이미 발급한 인증서의 서명이 곧바로 무효화되는 것은 아닙니다. 따라서 인증서 검증과 별개로 해당 Agent가 여전히 접속을 허용받은 상태인지 확인해야 합니다.

마치며 📕

이번 과정을 통해 '식별', '최초 인증', '서명 검증'이 서로 다른 역할을 한다는 점을 확인했습니다. 식별 정보는 대상을 구별하고, 최초 등록용 키는 초기 인증 자격을 확인합니다. CSR 서명은 공개키에 대응하는 개인키의 소유를 보여주며, CA의 인증서 서명은 검증된 공개키와 신원 정보를 연결합니다.

 

TLS와 mTLS에서는 발급된 인증서를 통신 상대의 신원을 확인하는 데 활용할 수 있습니다. 다만 인증서 하나만으로 보안이 완성되지는 않습니다. 키 보관, 신뢰 체인 검증, 유효기간과 폐기 상태 확인이 함께 이뤄져야 합니다. 신뢰는 한 번의 인증으로 끝나는 것이 아니라 연결의 각 단계에서 확인해야 하는 조건입니다.

다음 글 예고 🤩

다음 글에서는 대시보드를 주제로, 유형별 특징과 데이터 시각화 방식, 필요한 정보를 효과적으로 전달하기 위한 화면 구성의 기술적 요소를 살펴보려 합니다.


참고 자료

• RFC 2986: PKCS #10 Certification Request Syntax: https://www.rfc-editor.org/rfc/rfc2986

• RFC 5280: X.509 Certificate and CRL Profile: https://www.rfc-editor.org/rfc/rfc5280

• RFC 8446: TLS 1.3: https://www.rfc-editor.org/rfc/rfc8446