이전의 몇몇 포스팅과 관련된 토이프로젝트에 대해 이야기 해보고자 한다.
전자봉투를 활용하는 가상 시나리오를 작성하고, 그에 맞는 시스템을 구현하는 프로젝트였다. 그리고 과목 특성에 맞게 시큐어 코딩 가이드라인을 적용하고 분석하도록 했다.
내가 처음 작성했던 가상 시나리오는 기업 내에서 전자봉투를 활용하여 보안 로그를 전달하는 시스템에 대한 내용이었다.
하지만 이 시나리오를 작성하는 내내 실제 기업 내에서는 자체 시스템을 쓸 텐데 굳이 이렇게 쓸 필요가 있을까 하는 생각이 마음에 계속 걸렸다.
교수님께 피드백을 받은 결과, 조금 더 괜찮은 시나리오로 변경하게 되었고.. 기간이 넉넉하지는 않았지만 싹 갈아엎게 되었다 ㅎㅎ
그렇게 전체 수정된 내 프로젝트 IRMS 내용은 아래와 같다.
발표 대본을 그대로 차용한 기획서의 내용을 그대로 가져왔다..
2025년 5월, 국내 보안 기업인 B는 자사에서 운영 중인 Threat Intelligence 플랫폼을 통해 국제적으로 보고된 APT 공격 기법과 유사한 패턴으로 보이는 네트워크 활동을 감지하게 됩니다.
B 회사의 침해사고분석팀은 이를 분석했고, 악성 행위의 흐름과 명령 제어 경로, 침해 지표와 잠재적인 피해범위를 정리한 위협 인텔리전스 보고서를 작성했습니다.
이 보고서에는 백도어의 모듈과 침투 경로, 포렌식 분석 결과 등이 포함되어 있으며, 이 정보가 유출될 경우, attacker가 공격을 정교화할 수 있는 수준의 민감한 자료가 담겨져 있습니다.
이 정보를 국가 주요 기반시설을 운영하는 에너지 공공기관인 A에 전달할 필요가 있다고 판단했습니다.
사이버 공격에 취약할 경우, A 기관은 전국의 전력망 관제와 설비 제어를 담당하는 핵심 기관이기 때문에 국가 단위 혼란으로 이어질 수 있는 상황이었습니다.
이메일이나 클라우드 기반의 파일 전송 방식은 위변조 또는 중간자 공격의 위험이 있고, A 기관은 내부망이 인터넷과 분리된 망분리 환경이기 때문에 외부 메일의 파일 첨부도 어렵다고 판단하여 B 회사는 전자봉투 기반의 전달 방식을 사용하기로 결정합니다.
국내 보안 회사 B의 cert1은 보고서 파일을 AES-256 알고리즘을 사용하여 대칭키로 문서를 암호화합니다.
대칭키는 에너지 공공기관인 A의 공개키를 이용해 RSA 방식으로 암호화됩니다.
암호화된 대칭키와 암호화된 문서 파일은 전자봉투 형태로 패키징됩니다.
이때 봉투 자체에 SHA-256 해시 기반의 디지털 서명을 부여하여 무결성 검증이 가능하도록 합니다.
만약 교환 방식이 잘못된다면, 공격자가 위조된 키를 사용해 중간자 공격을 시도할 수 있게 됩니다.
여기서 중간자 공격이란 네트워크, 웹 또는 브라우저 기반 보안 프로토콜의 취약성을 악용하여 합법적인 트래픽을 우회하고 피해자의 정보를 훔치는 방식을 의미하며,
예시로 이메일 하이재킹, 세션 하이재킹 등이 있습니다.
이런 위험을 방지하기 위해 보안 회사인 B 측에서는 공공기관인 A 쪽에 공인인증기관(CA)에서 발급받은 PEM 형식의 공개키 인증서를 요청했습니다.
이 인증서를 이전에 A와 B 기관에 설정된 VPN 기반의 SFTP 보안 채널을 통해 안전하게 전달할 수 있었습니다.
B는 CA의 루트 인증서와, 인증서 폐기 목록인 CRL, 온라인 인증 상태 확인 프로토콜인 OCSP 등을 활용해 해당 키의 유효성과 진위를 확인한 뒤에 암호화에 활용했습니다.
이전의 과정을 거쳐 생성된 전자봉투는 외부망을 통해 전달된 후, 에너지 공공기관인 A의 DMZ 구간에 위치한 보안 중계 시스템을 통해 내부망으로 전송됩니다.
전달받은 전자봉투는 A 기관의 보안 시스템에서 다음과 같은 절차로 복호화 및 검증됩니다.
먼저, PEM 인증서 기반의 RSA 개인키를 활용하여 전자봉투 안에 포함된 암호화된 대칭키를 복호화합니다.
다음으로, 복호화된 대칭키를 사용하여 실제 암호화되어 있던 보고서 파일의 내용을 복호화하게 됩니다.
마지막으로 전자봉투에 함께 포함된 SHA-256 해시 기반의 디지털 서명을 이용해 위변조 여부를 검증하게 됩니다.
이 과정을 통해 에너지 공공기관인 A는 원본 그대로의 보안 문서를 안전하게 열람할 수 있는 환경을 갖출 수 있게 됩니다.

가상 시나리오 중 제가 구현한 단계에 대해 설명하겠습니다
KeyService.generateKeyPairForUser() 메소드가 실행되어, RSA 2048비트의 키쌍이 생성된 후, PEM 형식으로 DB에 저장됩니다.EnvelopeController.uploadFile() 메소드에서 EnvelopeService.saveEncryptedEnvelope() 메소드를 호출하게 됩니다.EnvelopeService.transferEnvelope()에서EnvelopeService.verifyAndDecryptEnvelope() 메소드에서다음은 코드 리뷰입니다.
저는 52번 규칙인 Avoid in-band error indicators를 적용한 코드를 가져왔습니다.
제가 작성한 코드 중 KeyController 클래스의 generateKeys 메소드를 보게 되면 resolveToken()이 null을 반환하더라도 체크 없이 getUsernameFromToken을 호출하게 되는데
이때 토큰이 null일 경우 내부적으로 JwtParser가 토큰 파싱을 시도하며 NullPointerException이 발생하게 됩니다.
저는 문제 해결을 위해 예외를 발생시키도록 코드를 추가하여 NullPointerException이 발생할 수 있는 상황을 피하도록 했습니다.

REFERENCE
https://www.fortinet.com/kr/resources/cyberglossary/man-in-the-middle-attack
https://www.entrust.com/ko/resources/learn/what-is-pki
https://raptor-hw.net/xe/know/147875
Java Coding Guidelines 75 Recommendations for Reliable and Secure Programs
조금 부실하지만 발표 ppt는 내 git에 올려두었다.
새로운 언어로 새롭게 시도를 하려니 공부 시간도 부족했고, 웹 개발 지식도 충분하지 않아서 구글링으로 겨우겨우 일주일을 밤새다시피 매달려서 마무리했다.. 매일 오후 스카에 출근해서 스카메이트랑 새벽 6시에 집가는 일을 반복하니 체력이 말이 아니긴 했지만 벌써 추억이 미화되고 있다..^^..
다른 팀은 2인 1조로 진행되었던 곳도 있었는데 나는 혼자 너무 욕심을 부린거 아닌가 고민도 많이 했지만, 그리고 비록 이런일 저런일이 겹쳐서 버거웠지만 어찌되었든 마무리를 할 수 있어서 다행이었고, 각 잡고 프로젝트를 해보고 싶다는 생각이 들었다.