middlemoon
AWS Lambda, API Gateway 를 활용하여 비대칭키 발급 구현 본문
이번 쿠팡사태와 관련하여 보안이 날이 갈수록 더욱 중요해진다는것을 체감한다.
잘 짜여진 코드와, 인프라가 있어도 보안에 취약하게 되면 아무것도 아니라는 사실을 깨닫게되는 요즘이다.
https://m.boannews.com/html/detail.html?tab_type=1&idx=140661
[쿠팡 해킹] ‘방치된 권한’과 ‘죽은 관제’...890억 보안 투자 쿠팡, 기본에 뚫렸다
국내 최대 이커머스 기업 쿠팡에서 3370만건의 개인정보 유출 사고가 단순 해킹이 아닌 ‘총체적 인재’라는 정황이 드러나고 있다. 연간 900억에 육박한 보안 예산과 200명이 넘는 전담 인력을 운
m.boannews.com
회사에서 나온 주제로 우리의 시스템에도 영향이 있지않을까?라는 질문에서부터 시작하여 그 끝은 AWS에서 대칭키에서 비대칭키로 만들고, gitlab이나 public한 공간에서 private한 토큰값을 노출하게 되었을 때 그 결과는 치명적인 결과를 불러일으킴으로
만일의 사태를 대비하고자(?) 학습기록을 남겨보려한다.

실제 아직도 정말 많은 회사가 yml파일이나, 공통으로 나오는 필수값들을 그대로 담아놓은것을 볼수 있다.
보안상 소스를 올릴순 없지만 이런 상황에 직면하였다.

위와 같이 JWTS 형식의 값으로 Public 한 Key를 저 URL로 관리할 수 있게끔 만드는것으로 시작하였다.
필자가 진행했던 과정은 다음과 같다.
RSA 2048bit Private Key 생성
- 로컬에서 openssl로 RSA 키 쌍 생성
- private.pem + public.pem 확보
- private.pem만 AWS Secrets Manager에 저장하기 위한 준비 단계 완료

Private Key를 Secrets Manager에 안전하게 저장
- AWS Secrets Manager → 새 Secret 생성
- JSON 형태로 저장




Lambda 함수 생성 (JWKS 자동 생성기)
- 런타임: Python 3.12
- 역할(Role) 생성하여 Lambda에 연결
- Role에 SecretsManager GetSecretValue 권한 추가
→ 오류 해결해서 IAM 정상 작동시킴

import json
import boto3
from jose import jwk
secrets = boto3.client("secretsmanager", region_name="ap-northeast-2")
def lambda_handler(event, context):
# 1) Secrets Manager에서 private key + kid 가져오기
secret_value = secrets.get_secret_value(
SecretId="sts-rs256-key"
)
secret_json = json.loads(secret_value["SecretString"])
private_pem = secret_json["privatePem"]
kid = secret_json["kid"]
# 2) RSA private key 로드
key = jwk.construct(private_pem, algorithm="RS256")
# 3) 전체 JWK 읽기 (여기에는 private 요소 포함됨)
full_jwk = key.to_dict()
# 4) 공개키 정보만 골라서 재구성 (필터링)
public_jwk = {
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"kid": kid,
"n": full_jwk["n"], # 공개키 modulus
"e": full_jwk["e"] # 공개키 exponent
}
jwks = {"keys": [public_jwk]}
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(jwks)
}
Status: Succeeded
Test Event Name: default-test
The area below shows the last 4 KB of the execution log.
Response:
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"keys\": [{\"kty\": \"RSA\", \"alg\": \"RS256\", \"use\": \"sig\", \"kid\": \"2025-12-k1\", \"n\": \"wIS5_QlQZ6-k9HboX(보안)FoJefQ7Y2wsa5GRg_a8UODB(보안)7IXw\", \"e\": \"AQAB\"}]}"
}
Function Logs:
START RequestId: 56c91f4d-23a6-42c9-85ed-c8e77e60152d Version: $LATEST
END RequestId: 56c91f4d-23a6-42c9-85ed-c8e77e60152d
REPORT RequestId: 56c91f4d-23a6-42c9-85ed-c8e77e60152d Duration: 326.80 ms Billed Duration: 942 ms Memory Size: 128 MB Max Memory Used: 89 MB Init Duration: 615.10 ms
Request ID: 56c91f4d-23a6-42c9-85ed-c8e77e60152d
실제 비대칭키 기반 Public Keys의 토큰 값, n과, e의 조합으로 생김. 외부 접속서버에 저장하여 사용가능.
python-jose 환경을 위한 Lambda Layer 생성
- EC2 없이 zip을 직접 생성해서 Layer 업로드
- (Lambda Layer는 ‘추가 Python 라이브러리(jose, cryptography 등)’를 Lambda 환경에 설치하기 위해 필요하다.)
- Layers → python-jose-layer 생성
- Lambda에 해당 레이어 연결


Lambda 코드 구현 (완성된 JWKS Generator) - 해당부분 Lambda 함수 작성의 기능
- Secrets Manager에서 private key 가져오기
- python-jose로 RSA 공개키 파라미터(n, e) 추출
- kid, alg, use 들어간 JWKS(JSON Web Key Set) 자동 생성
- private key에 해당하는 값(p, q, d, dp, dq, qi 등)은 제거
- 테스트 성공하여 정상적인 JWKS 출력
API Gateway에 Lambda를 연결 (JWKS endpoint 생성)
- REST API 생성
- 리소스 /jwks 생성(dev아래 sts-jwks-generator를 입력해야함.)
- GET 메서드 → Lambda 함수 연결
- CORS 설정
- 배포(stage: dev)

최종 JWKS URL 확보

마무리하며)
이번 프로젝트는 JWT 서명 방식을 HS256에서 RS256으로 전환하기 위해
AWS Secrets Manager + Lambda + API Gateway 기반의 JWKS 공개키 제공 인프라를 구축한 작업입니다.
Private Key는 Secrets Manager에서 안전하게 보관하고,
Lambda는 이를 사용해 공개키(JWK)를 자동 생성,
API Gateway는 JWKS 엔드포인트를 통해 외부 서비스가 신뢰할 수 있는 공개키를 제공하도록 설계하였습니다.
이 구조 덕분에,
- 비밀키 노출 위험 감소
- 표준 기반의 공개키 검증 환경 구축
- 향후 Key Rotation 자동화까지 확장 가능
이라는 보안적 이점을 얻을 수 있었습니다.
이번 프로젝트는 "보안 사고를 사전에 예방하는 인증 아키텍처를 직접 설계·구축해본 경험"이라는 점에서 의미가 크며,
향후 서비스 전체의 인증 안정성과 확장성을 높이는 기반이 될 것으로 예상됩니다.
'DevOps > AWS' 카테고리의 다른 글
| AWS ECS( Elastic Container Service) 로 배포하기 (0) | 2026.01.09 |
|---|---|
| AWS ECR(Elastic Container Registry) 생성하기 (0) | 2026.01.06 |
| AWS Bastion Host의 연결과 Jenkins 파이프라인 설계 - 프로젝트 (2) (0) | 2025.10.21 |
| AWS 클라우드의 VPC 구성부터 EC2 생성까지 - 프로젝트(1) (1) | 2025.10.15 |
| AWS - EC2 인스턴스 생성해서 SSH에 AWS 연결하기(1) (0) | 2022.12.28 |