회사 프로그램에 로그인 하기 위해서 인증 방식을 선택할 수 있도록 되어있는데, 그 중 OTP 인증 방식이 있어서 정리해봄!!!
일단 OTP에 대해서 알아보자!!
OTP란, One Time Password의 약자로, 일회용 비밀번호 생성기를 말한다. 이는 고정된 패스워드 대신 무작위로 생성되는 일회용 패스워드로 사용자를 인증하는 방식이다. 한번 사용하고 난 패스워드는 폐기되어 재사용이 불가능하다.
OTP
를 사용하는 가장 큰 이유는 보안
때문이다. 일반적인 아이디/패스워드를 사용하는 인증 기법의 경우 패스워드 노출이 가장 우려되는 사항인데, 매번 같은 방식으로 패스워드를 사용하다 보면 해킹이나 추측등으로 유출이 될 수 있다.
OTP
는 이와 같은 취약성을 보완하여 보안을 강화하기 위해 도입되었다. 로그인할때마다 서로 다른 패스워드를 이용함에 따라 패스워드 노출을 최소화 하고 보안을 강화한다.
출처 : 한국정보통신기술협회_ 생활 속 표준 - 금융사기 피해 방지, 일회용 패스워드(OTP)로
현재 많이 사용되고 있는 Google OTP
, 은행 OTP
는 대부분 TOTP 기반
으로 동작되고 있다. 이 외에도 HOTP 기반
동작 방식이 있지만 이건 나중에 정리 ..
TOTP
는 HOTP 기반으로 나왔으며, HOTP와 다르게 시간(Time) 기반
이라는 특징이 있다.
TOTP는 처음 바코드나 일정 길이의 문자열이 secretKey가 된다. 따라서 이 키를 저장해두면 OTP를 잃어버려도 복구가 가능하다.
또한, TOTP는 특정 시간 마다 다음 값으로 변경된다. 다만 클라이언트와 서버의 시간 차이 때문에 인증이 제대로 되지 않는 경우가 있는데 이럴 경우 기기의 시간이 현재 시간과 일치한지 확인 후 일치하지 않다면 시간 동기화가 필요하다.
이번에 작성할 글에서 사용하는 인증 방식도 TOTP 기반
인증 방식이다!!!
일단 필요한 모듈을 설치 해 줘야 하는데, 총 2개의 모듈을 설치 해 줄 것이다.
npm install --save speakeasy
npm install --save qrcode
일단 여기서 qrcode
는 말그대로 QR코드를 생성하는 모듈이다.
speakeasy
는 좀 생소 할 수 있는데, 해당 모듈에 대한 설명은 다음과 같다.
"speakeasy"는 Node.js에서 사용할 수 있는 오픈 소스 모듈 중 하나로, 2단계 인증(2FA)을 구현하기 위한 도구로 널리 사용됩니다. 이 모듈을 사용하면 웹 애플리케이션에서 토큰 기반의 2단계 인증을 간단하게 구현할 수 있습니다.
주로 Time-based One-Time Passwords (TOTP)와 HMAC-based One-Time Passwords (HOTP)를 생성하고 검증하는 데 사용됩니다. 이러한 암호화된 비밀번호들은 일반적으로 QR 코드를 통해 사용자의 스마트폰 앱(예: Google Authenticator, Authy)에 등록됩니다.
이제 본격적으로 QR 코드를 생성해야한다.
speakeasy
모듈을 이용해 생성한 시크릿키를 기반으로 QR을 생성해야 하기 때문에, 일단 시크릿키를 먼저 생성 하고 -> 해당 시크릿 키로 QR코드용 URL 생성 -> 생성된 URL을 기반으로 QR코드 생성
단계로 진행하면 된다.
const speakeasy = require('speakeasy');
const QRcode = require('qrcode');
const secret = speakeasy.generateSecret({
length: 20, // 비밀키의 길이를 설정 (20자리)
name: userId, // 사용자 아이디를 비밀키의 이름으로 설정
algorithm: 'sha512' // 해시 알고리즘 지정 (SHA-512 사용)
})
var url = speakeasy.otpauthURL({
secret: secret.ascii, // OTP 인증을 위한 비밀키 (ASCII 형식)
issuer: 'OTP TEST', // 발급자(issuer) 정보 설정
label: userId, // 사용자 아이디를 라벨로 사용하여 OTP의 라벨 설정
algorithm: 'sha512' // 해시 알고리즘 지정 (SHA-512 사용)
})
QRcode.toDataURL(url, function(err, imageData) {
loginResult.imageData = imageData; // QR 코드 이미지 데이터 추가
loginResult.code = 'S03'; // 로그인 결과 코드 설정
loginResult.secret = secret.base32; // 생성된 비밀키(base32 형식) 추가
// HTTP 응답으로 loginResult 객체를 전송
res.send(loginResult);
});
speakeasy.generateSecret() : generateSecret 메서드를 이용하여 비밀키 생성
speakeasy.otpauthURL() : otpauthURL 메서드를 이용하여 OTP의 인증 UTL 생성
QRcode.toDataURL() : QR 코드를 생성하고 생성된 이미지를 객체에 추가하여 전송
여기서 생성된 imageData를 HTML에서 img 태그에 넣어주면 QR코드로 띄워줄 수 있다!!
img 태그가 있는 코드를 만들어주고 거기에 저 데이터 넘겨주면 된다~
인터넷에 검색하면 QR 코드 생성 해 주는 웹 사이트 있으니까 거기서 테스트를 먼저 해 보는것도 좋을 것 같다!!
하여튼 여기까지 해 주면 OTP용 QR을 생성 해 줄 수 있다!
QR 생성까지는 완료됐고, 다음 글에서는 생성된 QR로 검증을 하는 방법과 관련 에러에 대해 작성해봐야겠다~~~