Advertisement
Guest User

Untitled

a guest
Dec 4th, 2016
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.10 KB | None | 0 0
  1. import java.lang.reflect.UndeclaredThrowableException;
  2. import java.security.GeneralSecurityException;
  3. import java.text.DateFormat;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import javax.crypto.Mac;
  7. import javax.crypto.spec.SecretKeySpec;
  8. import java.math.BigInteger;
  9. import java.util.TimeZone;
  10.  
  11.  
  12. /**
  13. * This is an example implementation of the OATH
  14. * TOTP algorithm.
  15. * Visit www.openauthentication.org for more information.
  16. *
  17. * @author Johan Rydell, PortWise, Inc.
  18. */
  19.  
  20. public class TOTP {
  21.  
  22. private TOTP() {}
  23.  
  24. /**
  25. * This method uses the JCE to provide the crypto algorithm.
  26. * HMAC computes a Hashed Message Authentication Code with the
  27. * crypto hash algorithm as a parameter.
  28. *
  29. * @param crypto: the crypto algorithm (HmacSHA1, HmacSHA256,
  30. * HmacSHA512)
  31. * @param keyBytes: the bytes to use for the HMAC key
  32. * @param text: the message or text to be authenticated
  33. */ private static byte[] hmac_sha(String crypto, byte[] keyBytes,
  34. byte[] text){
  35. try {
  36. Mac hmac;
  37. hmac = Mac.getInstance(crypto);
  38. SecretKeySpec macKey =
  39. new SecretKeySpec(keyBytes, "RAW");
  40. hmac.init(macKey);
  41. return hmac.doFinal(text);
  42. } catch (GeneralSecurityException gse) {
  43. throw new UndeclaredThrowableException(gse);
  44. }
  45. }
  46.  
  47.  
  48. /**
  49. * This method converts a HEX string to Byte[]
  50. *
  51. * @param hex: the HEX string
  52. *
  53. * @return: a byte array
  54. */
  55.  
  56. private static byte[] hexStr2Bytes(String hex){
  57. // Adding one byte to get the right conversion
  58. // Values starting with "0" can be converted
  59. byte[] bArray = new BigInteger("10" + hex,16).toByteArray();
  60.  
  61. // Copy all the REAL bytes, not the "first"
  62. byte[] ret = new byte[bArray.length - 1];
  63. for (int i = 0; i < ret.length; i++)
  64. ret[i] = bArray[i+1];
  65. return ret;
  66. }
  67.  
  68. private static final long[] DIGITS_POWER
  69. // 0 1 2 3 4 5 6 7 8
  70. = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000, 10000000000L };
  71. /**
  72. * This method generates a TOTP value for the given
  73. * set of parameters.
  74. *
  75. * @param key: the shared secret, HEX encoded
  76. * @param time: a value that reflects a time
  77. * @param returnDigits: number of digits to return
  78. *
  79. * @return: a numeric String in base 10 that includes
  80. * {@link truncationDigits} digits
  81. */
  82.  
  83. public static String generateTOTP(String key,
  84. String time,
  85. String returnDigits){
  86. return generateTOTP(key, time, returnDigits, "HmacSHA1");
  87. }
  88.  
  89.  
  90. /**
  91. * This method generates a TOTP value for the given
  92. * set of parameters.
  93. *
  94. * @param key: the shared secret, HEX encoded
  95. * @param time: a value that reflects a time
  96. * @param returnDigits: number of digits to return
  97. *
  98. * @return: a numeric String in base 10 that includes
  99. * {@link truncationDigits} digits
  100. */
  101.  
  102. public static String generateTOTP256(String key,
  103. String time,
  104. String returnDigits){
  105. return generateTOTP(key, time, returnDigits, "HmacSHA256");
  106. } /**
  107. * This method generates a TOTP value for the given
  108. * set of parameters.
  109. *
  110. * @param key: the shared secret, HEX encoded
  111. * @param time: a value that reflects a time
  112. * @param returnDigits: number of digits to return
  113. *
  114. * @return: a numeric String in base 10 that includes
  115. * {@link truncationDigits} digits
  116. */
  117.  
  118. public static String generateTOTP512(String key,
  119. String time,
  120. String returnDigits){
  121. return generateTOTP(key, time, returnDigits, "HmacSHA512");
  122. }
  123.  
  124.  
  125. /**
  126. * This method generates a TOTP value for the given
  127. * set of parameters.
  128. *
  129. * @param key: the shared secret, HEX encoded
  130. * @param time: a value that reflects a time
  131. * @param returnDigits: number of digits to return
  132. * @param crypto: the crypto function to use
  133. *
  134. * @return: a numeric String in base 10 that includes
  135. * {@link truncationDigits} digits
  136. */
  137.  
  138. public static String generateTOTP(String key,
  139. String time,
  140. String returnDigits,
  141. String crypto){
  142. // int codeDigits = Long.decode(returnDigits).intValue();
  143. int codeDigits = 10;
  144. String result = null;
  145.  
  146. // Using the counter
  147. // First 8 bytes are for the movingFactor
  148. // Compliant with base RFC 4226 (HOTP)
  149. while (time.length() < 16 )
  150. time = "0" + time;
  151.  
  152. // Get the HEX in a Byte[]
  153. byte[] msg = hexStr2Bytes(time);
  154. byte[] k = hexStr2Bytes(key);byte[] hash = hmac_sha(crypto, k, msg);
  155.  
  156. // put selected bytes into result int
  157. int offset = hash[hash.length - 1] & 0xf;
  158.  
  159. int binary =
  160. ((hash[offset] & 0x7f) << 24) |
  161. ((hash[offset + 1] & 0xff) << 16) |
  162. ((hash[offset + 2] & 0xff) << 8) |
  163. (hash[offset + 3] & 0xff);
  164.  
  165. long otp = (long) (binary % DIGITS_POWER[codeDigits]);
  166.  
  167. result = Long.toString(otp);
  168. while (result.length() < codeDigits) {
  169. result = "0" + result;
  170. }
  171. return result;
  172. }
  173.  
  174. public static void main(String[] args) {
  175. // Seed for HMAC-SHA1 - 20 bytes
  176. String seed = "3132333435363738393031323334353637383930";
  177. // Seed for HMAC-SHA256 - 32 bytes
  178. String seed32 = "3132333435363738393031323334353637383930" +
  179. "313233343536373839303132";
  180. // Seed for HMAC-SHA512 - 64 bytes
  181. String seed64 = "3132333435363738393031323334353637383930" +
  182. "3132333435363738393031323334353637383930" +
  183. "3132333435363738393031323334353637383930" +
  184. "31323334";
  185. long T0 = 0;
  186. long X = 30;
  187. long testTime[] = {59L, 1111111109L, 1111111111L,
  188. 1234567890L, 2000000000L, 20000000000L};
  189.  
  190. String steps = "0";
  191. DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  192. df.setTimeZone(TimeZone.getTimeZone("UTC"));
  193. try {
  194. System.out.println(
  195. "+---------------+-----------------------+" +
  196. "------------------+--------+--------+");
  197. System.out.println(
  198. "| Time(sec) | Time (UTC format) " +
  199. "| Value of T(Hex) | TOTP | Mode |");
  200. System.out.println(
  201. "+---------------+-----------------------+" +
  202. "------------------+--------+--------+");
  203.  
  204. for (int i=0; i<testTime.length; i++) {
  205. long T = (testTime[i] - T0)/X;
  206. steps = Long.toHexString(T).toUpperCase();
  207. while (steps.length() < 16) steps = "0" + steps;
  208. String fmtTime = String.format("%1$-11s", testTime[i]);
  209. String utcTime = df.format(new Date(testTime[i]*1000));
  210. System.out.print("| " + fmtTime + " | " + utcTime +
  211. " | " + steps + " |");
  212. System.out.println(generateTOTP(seed, steps, "8",
  213. "HmacSHA1") + "| SHA1 |");
  214. System.out.print("| " + fmtTime + " | " + utcTime +
  215. " | " + steps + " |");
  216. System.out.println(generateTOTP(seed32, steps, "8",
  217. "HmacSHA256") + "| SHA256 |");
  218. System.out.print("| " + fmtTime + " | " + utcTime +
  219. " | " + steps + " |");
  220. System.out.println(generateTOTP(seed64, steps, "8",
  221. "HmacSHA512") + "| SHA512 |");
  222.  
  223. System.out.println(
  224. "+---------------+-----------------------+" +
  225. "------------------+--------+--------+");
  226. }
  227. }catch (final Exception e){
  228. System.out.println("Error : " + e);
  229. }
  230. }
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement