250x250
Notice
Recent Posts
Recent Comments
관리 메뉴

탁월함은 어떻게 나오는가?

구글 OTP 2FA 인증 방법 구현과 TOTP 원리에 대해서 공부해보자 (node.js, react) 본문

[Snow-ball]프로그래밍(컴퓨터)/여러가지

구글 OTP 2FA 인증 방법 구현과 TOTP 원리에 대해서 공부해보자 (node.js, react)

Snow-ball 2023. 12. 9. 20:11
반응형

구글 OTP 2FA인증에 대해서 구현해보고 싶어서 테스트를 진행해보았다. 개인적으로 나는 구글에서 열어주는 api를 사용하는 줄 알았는데, 전혀 아니였다.

 

이 글에는 TOTP에 관한 간단한 설명과 코드에 적용한 방법만 적을 예정이다. 좀 더 자세히 알고 싶다면 밑에 레퍼런스 참조하는것을 추천한다.

 

 

 

 

 


 

 

 

2FA 란?

- 2FA는 Two-Factor Authentication 의 준말로, 유저의 보안을 강화하기 위해 1차 로그인 과정이외의 추가 인증 과정을 말한다.

- 최근 많은 웹 사이트, 게임 등에서 활용되고 있는 OTP, 모바일을 통한 추가 인증 등이 이에 해당된다.

- 인증은 아래의 3가지 유형으로 크게 분류할 수 있다.

- 일반적으로 지식기반의 인증에 더불어 또 다른 인증 방식을 추가하여 구현이 된다.

 

지식 기반 인증

사용자가 알고 있는 정보, 유출되시 쉽다는 단점이 있음.

- 아이디, 패스워드, 핀번호

 

소유 기반 인증

사용자가 소유하고 있는 것을 통한 인증.

- OTP, 스마트 카드, 토큰, USB 키, SMS 인증 등

 

생체 인증

사용자 그 자체를 증명할 수 있는 수단

- 지문 인식, 홍체 인식

 

위의 3가지 유형이 존재하며, Google Authenticator는 소유 기반의 TOTP 기반 인증을 수행한다.

 

 

 


 

 

TOTP에 대해서 알기전에 OTP에 대해서 먼저 알아보자.

 

OTP란?

One Time Password 의 준말로 무작위로 생성되는 1회용 비밀번호를 이용하는 방식이다. 우리가 은행에서 발급받아 사용하는 하드웨어 OTP 기기부터 게임 로그인에활용하는 OTP 앱 모두를 포함한다.

 

TOTP란 그리고 언제 사용할까?

TOTP(Time-based One-Time Password, 시간 기반 일회용 암호)는 일정한 시간 간격으로 변경되는 고유한 암호를 생서하기 위해 시간 기반 알고리즘을 사용하는 2단계 인증(2FA)의 한 유형이다. HOTP의 개선된 버전이라고 생각하면 좋다. HOTP는 이벤트 발생 후 counter라는 변수로 검사를 했다면 TOTP는 앞서 이야기한대로 시간을 기준으로 검사를 진행한다.

 

TOTP는 일반적으로 Google Authenticator 또는 Microsoft Authenticator와 같이 모바일 앱과 함께 사용된다. 사용자가 TOTP를 계정에 설정할 때, 먼저 2FA를 활성화하고 계정을 모바일 앱에 연결한다. 그런 다음 앱은 일회용 암호를 계산하는 데 고유한 비밀 키를 생성한다. 비밀 키는 일반적으로 QR 코드로 표시되며 사용자는 이를 휴대폰으로 스캔하여 앱에 가져온다.

 

Conter를 대체하는 시간 값은 아래와 같이 계산된다.

 

TOTP사용할 때 사용자가 계정에 로그인하면, 일반 비밀번호 외에 앱에서 생성된 현재 TOTP 코드를 입력하라는 메시지가 나온다. TOTP 코드는 일정 시간 동안 (일반적으로 30초, Google Authenticator의 경우는 default 30초)만 유효하며, 각 시간 간격이 끝날 때마다 앱에서 자동으로 새로운 코드가 생성된다.

 

TOTP는 계정 로그인에 추가적인 보안 기능을 제공하여, 공격자가 사용자의 비밀번호와 모바일 기기에 접근 권한을 모두 가져야만 성공적으로 로그인할 수 있다. TOTP는 상대적으로 구현과 사용이 쉽기 때문에 많은 조직에서 보안 수준을 향상시키기 위한 인기있는 선택지이다.

 

TOTP는 온라인 뱅킹, 전자 상거래, 이메일, 소셜 미디어 등 사용자 계정을 보호하기 위해 추가적인 보안 기능이 필요한 경우에 일반적으로 사용된다. 또한 결제 카드 산업 데이터 보안 표준(PCI DSS), 건강 보험 이동성 및 책임 법(HIPAA), 일반 개인정보 보호 규정(GDPR)과 같은 규정 준수를 충족하기 위해 사용된다.

 

만약 사용자가 비밀번호만 사용하는 것 이상으로 로그인 프로세스의 보안을 강화하고자 한다면 개인 계정에서 TOTP를 선택할 수 있다. 또한 기업 네트워크 외부에서 회사 자원에 액세스해야 하는원격 작업자에게도 유용할 수 있다. TOTP는 민감한 데이터에 대한 무단 액세스를 방지하기 위해 추가적인 보호층을 제공하기 때문이다. 전반적으로 TOTP는 비밀번호에 추가로 두 번째 인증 요소를 요구함으로써 사용자 계정의 보안을 간단하면서도 효과적으로 향상시키는 방법이다. TOTP는 많은 다양한 애플리케이션과 산업에서 민감한 데이터를 보호하고 규정 준수 요구사항을 충족하기 위해 일반적으로 사용된다.

 

 

 


 

 

 

HOTP vs TOTP

 

 

 


 

 

 

사용자에 의한 OTP 발급진행 프로세스

 

 

 


 

 

 

적용 코드:

 

1. 서버 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const speakeasy = require("speakeasy");
const qrcode = require("qrcode");
const express = require("express");
const app = express();
const cors = require("cors");
app.use(cors());
app.use(express.json());
 
const PORT = 8080;
const ALGORITHM = "sha512";
app.listen(PORT, () => console.log(`PORT: ${PORT}`));
 
const secret = speakeasy.generateSecret({
  name"jh-test",
  length10,
  algorithm: ALGORITHM,
});
 
const url = speakeasy.otpauthURL({
  secret: secret.ascii,
  label: "jh@gmail.com",
  algorithm: ALGORITHM,
});
 
app.get("/qr", (req, res) => {
  qrcode.toDataURL(url, (err, data) => {
    res.json({
      img: data,
    });
  });
});
 
app.post("/auth", (req, res) => {
  const verified = speakeasy.totp.verify({
    secret: secret.base32,
    encoding: "base32",
    algorithm: ALGORITHM,
    token: req?.body?.token,
  });
 
  res.json({
    loggedIn: verified,
  });
});
 
cs

 

 

 

2. 프론트 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import "./App.css";
import axios from "axios";
import { useEffect, useState } from "react";
const url = "http://localhost:8080";
 
function App() {
  const [value, setValue] = useState("");
  const [qr, setQr] = useState("");
  useEffect(() => {
    axios
      .get(`${url}/qr`)
      .then((res) => {
        console.log(res);
        const image = res?.data?.img?.split(",");
        setQr(image);
      })
      .catch((err) => console.error(err));
  }, []);
 
  const handleInput = (e) => {
    e.preventDefault();
    setValue(e.target.value);
  };
 
  const handleSubmit = (e) => {
    e.preventDefault();
    axios
      .post(`${url}/auth`, { token: value })
      .then((res) => {
        if (res.data.loggedIn === truealert("성공");
        else alert("실패");
      })
      .catch((err) => console.error("err : ", err));
  };
 
  return (
    <>
      <div>구글 2FA OTP 인증이지롱</div>
      <div>
        <img src={qr} />
        <input type="text" onChange={handleInput} />
        <button onClick={handleSubmit}>Button</button>
      </div>
    </>
  );
}
 
export default App;
 
cs

 

 

 


 

 

 

결과: 

1. 서버, 프론트 서버를 실행하면 아래처럼 QR코드가 생성되는것을 확인할 수 있다.

 

2. 핸드폰으로 사용시 구글 플레이스토어에서 [ Authenticator ] 를 다운받는다. 들어가서보면 우측 하단의 [ + ] 를 눌러주면 Scan a QR code 가 있다. 그걸 눌러주고 QR 코드를 인식하면 6자리 숫자를 준다. (보안정책으로 스크린샷 불가)

 

3. Authenticator 에는 추가가 된다. 나의 경우에는 [ 290089 ] 이 발생해서 넣어줬다. 그러면 정상작동시 밑의 사진처럼 성공 메시지가 출력된다.

 

 

 

 

 

 

 

 

 

 

reference

* One Time Password(OTP)의 개념 및 동작방식. LDAP을 활용한 OTP 인증.

* TOTP(Time-based One-Time Password)란 무엇입니까? 그리고 언제 사용하나요?

* OTP? 2FA?

 

 

 

반응형
Comments