프로젝트를 진행하다보면 예상치 못한 오류들을 많이 마주하게 된다.
이번에 발생한 에러와 그 해결방안을 정리했다.
1. 문제상황
클라이언트 이미지를 저장하기 위해 백엔드 서버로 presignedURL을 요청하고, 서버는 요청을 확인한 후 presignedURL를 응답한다. 클라이언트는 전달받은 URL에 사진 첨부하여 PUT하면 사진 저장이 완료된다.
이 때, 안드로이드 높은 버전의 SDK(34)에서는 요청이 정상적으로 처리되는데, 낮은 버전의 SDK(26)에서는 handshake 오류가 발생했다.
2. 관련 이론
1) 안드로이드 SDK(Software Development Kit)
안드로이드 소프트웨어를 개발하기 위한 툴킷을 의미한다. 크게 세 가지로 구분할 수 있다.
- targetSDK: 앱이 기기에서 실행 시 실제로 사용되는 안드로이드 API 수준 → 팀 설정: 34 (Android 14, Upside Down Cake)
- compileSDK: 컴파일 시 사용되는 안드로이드 API 수준 -> 팀 설정: 34 (Android 14, Upside Down Cake)
- minSDK: 해당 앱이 동작할 수 있는 최소 안드로이드 API 수준 → 팀 설정: 26 (Android 8.0, Oreo)
- 권장사항: minSDK <= targetSDK == compileSDK
2) TLS/SSL Handshake
TLS(Transport Layer Security)는 인터넷상 커뮤니케이션을 위한 보안 프로토콜이다. SSL(Secure Sockets Layer)에서 발전한 것으로, 지금은 TLS라는 명칭으로 사용한다. 버전으로 TLS 1.0, 1.2, 1.3 등이 있다.
Handshake는 클라이언트와 서버간의 보안 연결을 설정하는 과정으로 클라이언트와 서버가 암호화된 통신을 시작하기 전에 여러 정보를 교환하는 단계로 구성된다. (세부 흐름은 다음 사이트 참고: Cloudflare-TLS 핸드셰이크의 원리는 무엇일까요?)
3. 문제원인
이번 기능은 안드로이드 담당자, 서버 담당자 모두 처음 구현해보는 기능이라서 어디가 문제인지 파악하는데 시간이 조금 걸렸다.
처음에는 안드로이드 targetSDK로 요청을 보냈을 때에는 요청이 정상적으로 처리되었기 때문에 서버측 문제가 아니라 안드로이드쪽 문제라고 생각하기도 했다. (최종 원인은 서버측에 있었다.)
TLS Handshake가 발생할 수 있는 원인은 다양한데, 대표적으로 아래와 같은 원인들이 있다.
원인 | 오류 | 해결 주체 |
잘못된 컴퓨터 시간 | 클라이언트 시간과 날짜가 잘못됨 | 클라이언트 |
브라우저 오류 | 브라우저 구성이 잘못됨 | 클라이언트 |
중간자 공격 | 제3자가 연결을 가로채거나 조작함, 방화벽이나 네트워크 장치 구성 이상 |
클라이언트, 서버 |
프로토콜 불일치 | 클라이언트에서 사용하는 프로토콜을 서버에서 지원하지 않음 상호 지원되는 TLS 프로토콜이 없음 |
서버 |
Cipher Suite 불일치 | 클라이언트에서 사용하는 암호 제품군을 서버에서 지원하지 않음 | 서버 |
잘못된 TLS/SSL 인증서 | 호스트 이름 불일치, 해지 또는 만료된 인증서 등 | 서버 |
이 중 우리 문제 원인은 Cipher Suite 불일치 문제였다.
Cipher Suite는 암호화 통신을 위한 여러 알고리즘과 프로토콜 조합을 의미한다. (참고: Cipher Suite in TLS/SSL)
서버에서 TLS 버전 1.2, 1.3을 설정해두었었고, 몇가지 Cipher Suite를 추가해두었었다.
SDK 34는 TLS 1.3 버전으로 통신을 해서 문제가 없었다.
SDK 26은 TLS 1.2 버전으로 통신을 했는데 서버에는 1.2 버전에서 사용할 수 있는 Cipher Suite 알고리즘이 없었다. 1.2에서 사용할 수 있는 Cipher Suite 알고리즘을 추가한 후 정상적으로 handshake가 이루어지는 것을 확인할 수 있었다.
4. 돌아보며
이번 에러는 안드로이드, 백엔드 각각 작업해서는 해결하기 어려운 문제였다. 서로의 분야가 긴밀하게 협업해야했고, 서로의 분야에 대한 이해도 필요했다. 개발 업무는 혼자 하는게 아니라는걸 다시 한번 체감할 수 있었다. 나중에 시간이 된다면 다른 분야에 대해서도 어느정도 학습해보고 싶다는 생각이 들었고, 그 전에 기초 이론 학습도 많이 해야겠다는 생각이 들었다.
참고자료
'우아한테크코스 > 레벨 3 - 프로젝트' 카테고리의 다른 글
[JPA] QueryDSL로 리스트 여러개 있는 데이터 가져오기 (0) | 2024.08.18 |
---|---|
[AWS] Spring Boot, S3를 활용한 이미지 업로드 (0) | 2024.07.28 |
[Git] Git branch 전략 (부제: branch 병합 방법 merge, rebase, squash) (1) | 2024.07.24 |
[CI/CD] Github Actions와 Docker를 활용한 CI/CD 구축, Self-Hosted Runner 적용 (0) | 2024.07.15 |