otp 구현하기
- 갑자기 otp를 구현하고 싶어졌다
 
Unix Epoch Time (Unix Time) 구하기
1  | new Date().getTime(); // unix time  | 
N 구하기
1  | const ts = 30; // 30초 간격으로 토큰을 생성할 것  | 
- unix time에서 토큰 생성간격 ts 만큼을 나누고 소수점은 버려서 N을 구한다
 
N 16진수 변환
1  | let N_hex = ('000000000000000' + N.toString(16)).substr(-16); // 16자리가 되도록 앞에 0 패딩추가  | 
- N을 16진수로 변환하는데 16자리가 되도록 처리
 
m 구하기 (시간 베이스 메세지 값)
1  | let m = Buffer.from(N_hex);  | 
- N_hex를 byte array로 변환
 
K 생성하기 (K : 공유키)
1  | const base32 = require('base32'); // base32 모듈 임포트  | 
- 랜덤값으로부터 20자리의 공유키 K 구하기
 - base32 모듈 설치
 - Math.random()으로 생성한 랜덤값을 12자리 문자열로 변환하고 base32인코딩하면 20자리의 문자열을 얻을 수 있음
 
HMAC hash 얻기
1  | const crypto = require('crypto');  | 
- 내장 모듈 crypto 에서 hmac hash를 얻을 수 있다
 
OTP 생성
1  | const offset = parseInt(Number(`0x${hmac_hash[hmac_hash.length - 1]}`), 10);  | 
- hmac_hash의 맨 마지막값을 offset으로 한다
 - hmac_hash offset부터 4바이트를 추출한고
 - offset 바이트에 
& 0x7f이진 연산 수행 - 나머지 3개 바이트에 대해 
& 0xFF연산 수행 - 6자리 토큰을 만든다고하면 그 결과의 뒤에서 6자리를 토큰으로 한다
 
개선사항
- 생성된 토큰 값이 일부분 동일하게 유지된다