본문 바로가기
iOS

[iOS] Access Token은 어디에 저장하는게 좋을까? UserDefaults? KeyChain?

by 코코종 2024. 1. 2.

 

안녕하세요 코코종입니다 :) 오늘은 마감 기한보다는 조금 일찍! 찾아왔습니다(물론 또 하루만에 써버리고 ㅌㅌ할 예정)

 

오늘은 최근에 제가 멘토로 활동하고 있는 새싹 3기 교육생분들 사이에 ‘키체인 붐’이 일었는데 이에 관련해 고민 포인트를 조금 던져볼 겸 작성하게 되었답니다. 내용이 많지 않을 것 같아 이번에는 글이 조금 짧을지도 모르겠네요!

 

결론부터 말하자면, 무조건 키체인에 저장하는게 UserDefaults에 저장하는 것보다 우수한 것은 아니다! 입니다

 

Access Token, Refresh Token이란?

 

정의에 대한 설명은 최대한 줄이려고 했는데 간단하게만 짚고 넘어가겠습니다.

 

JWT(Json Web Token)은 Json 객체에 인증에 필요한 정보들을 담아서 비밀키로 서명한 토큰으로 인증하는 방식입니다. 일반적으로 로그인이 있는 서비스에서는 로그인에 성공하면 jwt를 발급하게 됩니다. 이후 네트워크 요청에 이 jwt를 포함해서 신뢰할만한 사용자임을 인증해주게 됩니다. 그렇게 되면 HTTP는 무상태성(stateless)의 특성을 가지지만 매번 사용자에 대한 인증을 해 줄 필요가 없어지게 됩니다(🐶이득!)

 

다만 토큰을 탈취 당하게 되면 https://jwt.io/ 에서 확인할 수 있을 정도로 간단하게 정보를 열어볼 수 있습니다. 그렇다면 누군가가 나로 위장해서 이런 저런 행동을 할 수 있게 된다는 뜻이겠죠? 🤯 그렇기에 토큰의 ‘유효기간’이 필요한데 너무 길면 위험성이 높아지고 너무 짧으면 사용자가 불편해지는 문제가 발생합니다.

 

이를 해결하기 위해 탈취의 위험이 더 크고 만료 기간이 짧은 Access Token을 사용합니다. 또한 이 토큰이 만료되면 갱신하는 만료기간이 더 긴 Refresh Token을 두어 주기적으로 재발급해 위 문제를 해결하고자 합니다.

 

그래서 Access Token은 어디에 저장할까?

기호 1번 익숙한 UserDefaults

특징: 사용법이 초 간단하고 익숙하다.

기기에 어떤 값을 저장하고 꺼내쓴다? → 유저디폴트? 라고 가장 먼저 생각이 나실텐데요. 결론에서 스포했지만 여기에 토큰을 저장해도 괜찮습니다!

 

기호 2번 신흥강자(?) KeyChain

특징: 암호화가 되기 때문에 더 안전하다. 다만 사용법이 조금 불편하다.

간단하게 유저디폴트에 저장하고 끝내려고 했지만 access token에 대해 검색하다보니 어라라? ‘KeyChain’이라는 놈이 등장하네요? 여러 블로그를 읽다보니 누군가는 암호화를 해주기 때문에 여기에 저장하는게 정석이라고도 하고, UserDefaults에 저장하는것이 보안상 좋지 않다고도 하네요.

 

그렇다보니 많은 분들이 키체인에 저장을 하고 계셨고 이유를 여쭤보니 위와 같은 이유를 말씀하시더라구요.

여기서 제 글감이 탄생했답니다 하하하.(Thanks to 열심히 설명을 해주신 휴님)

과연 키체인이 무조건적으로 좋을지 같이 알아볼까요?

 

만약에 탈취를 당한다면?

'아니 키체인은 암호화가 된다며! 그럼 탈취 당해도 안전한거 아님??' 이라고 생각하실수도 있겠네요.

아니 암호화도 안되는데 유저디폴트에 저장했다가 탈취 당하면 어쩌려고요?

 

일반적으로 UserDefaults에 저장하는 것이 보안상 좋지 않다고 하는 이유가 ‘암호화’ 때문이라고 생각이 듭니다. 만약 해커가 내 기기에 저장된 암호화 되지 않은 UserDefaults를 가져가서 열어볼 수 있다면 access token 정보를 확인할 수 있을테니까요!

 

근데… UserDefaults를 열어볼 수 있을까요? ‘plist에서 확인이 가능한데요?’ 라고 생각하신다면 그건 시뮬레이터 한정이고 실기기에서는 해당 데이터를 확인할 수 없답니다 🙂 즉, 누군가가 내 기기를 해킹하거나 물리적 탈취를 하더라도 UserDefaults에 저장된 access token은 확인할 수 없다는 뜻이죠!!

'키체인 접근'에 저장된 암호
'암호'에 저장된 암호(캡쳐하면 안보이네요..)

 

또 키체인에는 단점이 될수도 있는 치명적인 특징이 존재하는데요, 물리적 탈취의 경우 키체인에 저장된 암호를 확인할 수 있다는 점 입니다. 아이폰에서는 설정의 '암호'를 통해, 맥의 경우는 '키체인 접근' 앱을 통해 확인이 가능합니다. 그렇다보니 기기에 암호화되어 저장했지만 해당 방법을 통해 원본을 확인할 수 있게 됩니다.

 

또한 이 방법으로 접근에 성공하게 된다면 모든 로그인 정보의 id, pw의 raw한 값을 확인할 수 있기 때문에 이때는 다른 앱의 보안마저 위협을 받을 수 있답니다.

 

극단적인 예시를 들어보자면 누군가가 저를 납치해서(?) 강제로 faceID나 touchID를 인증한다면 키체인에 저장된 제 모든 정보의 raw data를 확인할 수 있게 됩니다.

 

추가로 앞서 잠깐 소개했듯이 access token과 refresh token 자체가 토큰 탈취시에 최소한의 보안을 유지하기 위해 존재하는 개념입니다. 그렇기 때문에 access token의 갱신 주기가 짧게 설정된다면 누군가 이 토큰을 탈취를 해도 활용하기 어려울 수 있습니다 😈 이때 클라이언트에서는 refresh를 위해 interceptor를 잘 활용하는 것도 중요하겠네요!


마무리

위와 같은 이유 때문에 '무조건 키체인이 좋다!' 는 아닐 수 있습니다. 모든 기술에는 장단점이 존재하기 때문에 이런 지점들을 잘 비교하며 사용하는게 중요하다는 점!을 알려드리고자 이번 포스팅을 하게 되었답니다.

폭풍처럼 작성하다보니 부족한게 많지만 읽어주셔서 감사합니다~~