TimeEstimates.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. 'use strict';
  2. var Options = require('./Options.js');
  3. const SECOND = 1;
  4. const MINUTE = SECOND * 60;
  5. const HOUR = MINUTE * 60;
  6. const DAY = HOUR * 24;
  7. const MONTH = DAY * 31;
  8. const YEAR = MONTH * 12;
  9. const CENTURY = YEAR * 100;
  10. const times = {
  11. second: SECOND,
  12. minute: MINUTE,
  13. hour: HOUR,
  14. day: DAY,
  15. month: MONTH,
  16. year: YEAR,
  17. century: CENTURY
  18. };
  19. /*
  20. * -------------------------------------------------------------------------------
  21. * Estimates time for an attacker ---------------------------------------------------------------
  22. * -------------------------------------------------------------------------------
  23. */
  24. class TimeEstimates {
  25. translate(displayStr, value) {
  26. let key = displayStr;
  27. if (value !== undefined && value !== 1) {
  28. key += 's';
  29. }
  30. const {
  31. timeEstimation
  32. } = Options.default.translations;
  33. return timeEstimation[key].replace('{base}', `${value}`);
  34. }
  35. estimateAttackTimes(guesses) {
  36. const crackTimesSeconds = {
  37. onlineThrottling100PerHour: guesses / (100 / 3600),
  38. onlineNoThrottling10PerSecond: guesses / 10,
  39. offlineSlowHashing1e4PerSecond: guesses / 1e4,
  40. offlineFastHashing1e10PerSecond: guesses / 1e10
  41. };
  42. const crackTimesDisplay = {
  43. onlineThrottling100PerHour: '',
  44. onlineNoThrottling10PerSecond: '',
  45. offlineSlowHashing1e4PerSecond: '',
  46. offlineFastHashing1e10PerSecond: ''
  47. };
  48. Object.keys(crackTimesSeconds).forEach(scenario => {
  49. const seconds = crackTimesSeconds[scenario];
  50. crackTimesDisplay[scenario] = this.displayTime(seconds);
  51. });
  52. return {
  53. crackTimesSeconds,
  54. crackTimesDisplay,
  55. score: this.guessesToScore(guesses)
  56. };
  57. }
  58. guessesToScore(guesses) {
  59. const DELTA = 5;
  60. if (guesses < 1e3 + DELTA) {
  61. // risky password: "too guessable"
  62. return 0;
  63. }
  64. if (guesses < 1e6 + DELTA) {
  65. // modest protection from throttled online attacks: "very guessable"
  66. return 1;
  67. }
  68. if (guesses < 1e8 + DELTA) {
  69. // modest protection from unthrottled online attacks: "somewhat guessable"
  70. return 2;
  71. }
  72. if (guesses < 1e10 + DELTA) {
  73. // modest protection from offline attacks: "safely unguessable"
  74. // assuming a salted, slow hash function like bcrypt, scrypt, PBKDF2, argon, etc
  75. return 3;
  76. }
  77. // strong protection from offline attacks under same scenario: "very unguessable"
  78. return 4;
  79. }
  80. displayTime(seconds) {
  81. let displayStr = 'centuries';
  82. let base;
  83. const timeKeys = Object.keys(times);
  84. const foundIndex = timeKeys.findIndex(time => seconds < times[time]);
  85. if (foundIndex > -1) {
  86. displayStr = timeKeys[foundIndex - 1];
  87. if (foundIndex !== 0) {
  88. base = Math.round(seconds / times[displayStr]);
  89. } else {
  90. displayStr = 'ltSecond';
  91. }
  92. }
  93. return this.translate(displayStr, base);
  94. }
  95. }
  96. module.exports = TimeEstimates;
  97. //# sourceMappingURL=TimeEstimates.js.map