Java/Core

[펌]Java로 OTP 구현하기

EnterKey 2016. 1. 10. 12:04
반응형

단 50줄이면 Java에서 OTP를 구현할 수 있습니다.


제가 OTP를 구현해야겠다고 생각한 계기는,
'클라이언트와 서버 간 REST 통신시, 해커로부터 데이터 변조 공격을 막기 위해서 일회용 비밀번호(OTP)를 사용하면 어떨까?' 라는 생각에서 출발했습니다.
(적용은 안했지만, 누군가에게 도움이 되길 바라며...)

OTP (One Time Password)
고정된 패스워드 대신 무작위로 생성되는 일회용 패스워드를 이용하는 사용자 인증 방식.


은행에서 OTP 단말기나, OTP 카드를 사용해보신 분이라면 한 번쯤 생각해보셨을 겁니다.

'서버랑 통신하는건가..?'

사실, OTP는 단말기와 서버가 통신하는게 아닙니다.

미리 정의된 비밀키와 시간 정보를 토대로 Hash 처리하여 비밀번호를 만들어냅니다.

핵심은 시간입니다. 시간은 변하므로, 일정 시간(정하기 나름) 마다 비밀번호가 바뀌죠.

그리고, 똑같은 알고리즘으로 단말기에서 비밀번호를 생성하고, 서버에서 검증합니다.

같은 시간대에 만들어졌으므로 단말기와 서버에서 만든 패스워드는 동일합니다.


그럼 이제 OTP를 만들고 검증하는 클래스를 생성하고, 아래와 같이 상수를 정의합니다.

 private static final long DISTANCE = 30000; // 30 sec
 private static final String ALGORITHM = "HmacSHA1";
 private static final byte[] SECRET_KEY = "define your secret key here".getBytes();


그리고 비밀키와 시간에 따라 Hash 처리하여 패스워드를 생성하는 메소드를 아래와 같이 정의합니다.

 private static long create(long time) throws Exception {
  byte[] data = new byte[8];
  
  long value = time;
  for (int i=8; i-- > 0; value >>>= 8) {
   data[i] = (byte) value;
  }
  
  Mac mac = Mac.getInstance(ALGORITHM);
  mac.init(new SecretKeySpec(SECRET_KEY, ALGORITHM));
  
  byte[] hash = mac.doFinal(data);
  int offset = hash[20-1] & 0xF;
  
  long truncatedHash = 0;
  for (int i=0; i<4; ++i) {
   truncatedHash <<= 8;
   truncatedHash |= hash[offset+i] & 0xFF;
  }
  
  truncatedHash &= 0x7FFFFFFF;
  truncatedHash %= 1000000;
  
  return truncatedHash;
 }


마지막으로, OTP 클래스를 외부에서 사용할 수 있도록 public으로 create(), vertify() 메소드를 아래와 같이 정의합니다.

 public static String create() throws Exception {
  return String.format("%06d", create(new Date().getTime() / DISTANCE));
 }
 
 public static boolean vertify(String code) throws Exception {
  return create().equals(code);
 }

 

테스트 코드는 다음과 같습니다.

  String code = OTP.create();
  
  System.out.println("Created OTP : " + code);
  
  System.out.println("Vertify OTP : " + OTP.vertify(code));


30초(DISTANCE)마다 비밀번호가 변경되는 것을 확인할 수 있습니다.

 

참조 글

http://terms.naver.com/entry.nhn?docId=1380773&cid=40942&categoryId=32854

http://zero-gravity.tistory.com/m/post/221

http://www.javacodegeeks.com/2011/12/google-authenticator-using-it-with-your.html/comment-page-1/#comment-14663



출처: http://silentsoft.tistory.com/9

반응형