Time-based OTP 인증

Time-based One-time Password Algorithm

작동 방식

초기 등록시 seed값을 서버와 사용자의 기기에 각각 보관한다.

초기 등록

초기 등록시에는 서버에서 생성한 UUID값을 모바일 기기에서 받기 위해 네트워크 연결이 필요하다.

앱 → 서버 : 앱에서 사용자의 정보를 입력하고 서버로 전송한다

서버 → 앱 : 전송받은 정보를 데이터베이스에 저장하고 랜덤 값을 하나 생성하여 병사 고유 값(Seed 값)으로 저장하고 응답으로 Seed 값을 넘겨준다

앱 : 받은 Seed 값을 디바이스에 저장한다.

이때 Seed 값은 앱, 서버 두 곳에서 보유한다.

반납 과정

이때부터는 네트워크 연결 필요 없이 보유하고 있는 seed값과 현재 시간만을 이용하여 Time-based OTP값을 생성한다.

앱 : 반납 버튼을 누르면 위에 Seed값과 현재 시간 값을 기반으로 TOTP 값을 생성한다.

앱 : TOTP 값과 사용자 정보를 이용하여 QR코드를 생성한다.

앱 → 라즈 → 서버 : QR코드를 인식해 앱에서 생성한 TOTP 값과 사용자 정보를 서버로 전송한다

서버 : 서버에서 앱에서 받은 TOTP 값과, 서버에 저장되어 있는 병사 정보 중 Seed값을 불러와 현재 시간으로 TOTP 생성을 한다. 만약 앱에서 생성한 TOTP값과 서버에서 생성한 TOTP값이 동일하면 인증 완료.

위의 과정에서, 앱에서 TOTP 생성한 시간과 웹에서 TOTP 생성한 시간이 다를 수 있지만 TOTP 생성 과정에서 키가 유지되는 시간을 지정할 수 있기 때문에 문제를 해결할 수 있다.

테스트

간단하게 seed값에 따라 TOTP 값을 반환하는 API를 만들었다. 아래의 seed/ 경로 뒤에 40자리 임의의 숫자(seed 값)을 넣으면 된다.

https://osam.riyenas.dev/api/totp/generate/seed/{seed value}

예시

https://osam.riyenas.dev/api/totp/generate/seed/0123456789012345678901234567890123456789

새로고침을 할 때마다 키 값을 생성하는데 키 유지 시간은 10초로 설정하였다 따라서 10초 마다 TOTP 값이 변경되는 걸 볼 수 있다.

또한 시드 값만 서로 보유하고 있으면 네트워크 연결 없이도 인증을 진행할 수 있다.

시연 영상

Source Code

TOTP.class

CryptoType.class

사용 예시

Last updated

Was this helpful?