å¯äžã®è³ªåã¯ããã®ãããªããã°ã©ã ã¯æ¬åœã«ãŠãŒã¶ãŒã¢ã«ãŠã³ããä¿è·ããã®ã«åœ¹ç«ã€ã®ã§ããããïŒ ãã¡ãããã€ã³ã¿ãŒãããã»ãã¥ãªãã£ã®ãã®åŽé¢ã¯ãä»ã®ããã€ãã®ãã®ã»ã©éèŠã§ã¯ãããŸãããããšãã°ã
- é 延ã®å¢å ãŸãã¯CAPTCHAã®äœ¿çšã«ããWebããŒãžã®ãããã³ã°ãé²æ¢ããŸãã
- ãŠãŒã¶ãŒã¬ãã«ã§åå¥ã®ãå¡©ãã䜿çšããããªãé ãããã·ã¥é¢æ°ã䜿çšããŠããªãã©ã€ã³ãããã³ã°ãé²æ¢ããŸãã
- ãã¹ã¯ãŒãããã·ã¥ä¿è·ã
äžèšã®èŠå ãèæ ®ãããšãã¯ãããã¹ã¯ãŒãã»ãã¥ãªãã£ããã¹ãããããã°ã©ã ã¯æ¬åœã«éåžžã«ææã§ããããŠãŒã¶ãŒãå©ããããšãã§ãããšç¢ºä¿¡ããŠããŸã ã 2006幎ã«åºçããããPerfect PasswordsïŒSelectionãProtectionãAuthenticationããšããã¿ã€ãã«ã®æ¬ã§ãMark Burnettã¯ãããŸããŸãªæŒæŽ©ã®çµæãšããŠæããã«ãªã£ãæ°çŸäžã®ãã¹ã¯ãŒãã®äœ¿çšé »åºŠãèšç®ããŸããããŒã¿ã 圌ã¯ã9人ã«1人ã®ãŠãŒã¶ãŒããã®æã人æ°ã®ãããªã¹ããããã¹ã¯ãŒããéžãã ãšæžããŠããŸãã ãã®äžã«ã¯ãpassword1ãcompaqã77777777ãmerlinãrosebudãªã©ã®ãã¿ããªããããããããŸãã æšå¹ŽãBurnettã¯600äžã®ãã¹ã¯ãŒãã調æ»ããæ°ãã調æ»ãå®æœããŸããããä»åã¯ãã¹ã¯ãŒãã®99.8ïŒ ãæã人æ°ã®ãã10,000ã®ãªã¹ãã«ããã91ïŒ ã1000ã®æãäžè¬çãªãªã¹ãã«ãããŸãã ãã¡ãããçµæã¯èª¿æ»æ¹æ³ãšãµã³ãã«ãã€ã¢ã¹ã®åœ±é¿ã倧ããåããŸãããããšãã°ããããã®ãã¹ã¯ãŒãã®ã»ãšãã©ã¯æ¢ã«ã¯ã©ãã¯ãããããã·ã¥ããååŸããããããæåã¯ãªã¹ãå šäœãç°¡åã«ã¯ã©ãã¯ããããã¹ã¯ãŒãã«åã£ãŠããŸããã
æšæž¬ãããããã¹ã¯ãŒãã®ã¿ãããã«ãªã¹ããããŠããŸãããæ®ãã®å€§éšåã¯ãŸã ããªãäºæž¬å¯èœã§ãããå°èŠæš¡ãªãããã¯ãŒã¯æ»æã®çµæãšããŠã¯ã©ãã¯ãããå¯èœæ§ããããšæããŸãã ãããã£ãŠããŠãŒã¶ãŒãšã®çŽæ¥çãªå¯Ÿè©±ãéããŠããã®ãããªã¢ãã©ã€ã¶ãŒã¯ããå®å šãªãã¹ã¯ãŒããéžæããã®ã«æ¬åœã«åœ¹ç«ã€ãšä¿¡ããŠããŸãã ããããçŸæç¹ã§ã¯ã圌ãã¯ã»ãšãã©ã®å Žåã害ãåãŒãã ãã§ãïŒããã€ãã®ã¯ããŒãºããœãŒã¹ããã°ã©ã ã¯æ°ããŠããŸããïŒã ããããããèµ·ãã£ãŠããçç±ã§ãã
ãã¹ã¯ãŒãã®åŒ·åºŠã¯ããããåäœã§è¡šããããšã³ããããŒã®å€ã«ãã£ãŠæããã枬å®ãããŸãã ãšã³ããããŒã¯ãå¯èœãªãã¹ã¯ãŒãã®ã»ãããååã«ããããã®ãªãã·ã§ã³ã®æ°ãšããŠèšç®ãããŸãã æãç°¡åãªãã¹ã¯ãŒã匷床è©äŸ¡ã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã
# n: # c: : # (26 , , 62 â , , ) = n * lg(c) # 2
ãã®çŽæ¥éžæåæã¯ãæåãæ°åãèšå·ã®ã©ã³ãã ãªã·ãŒã±ã³ã¹ã§æ§æããããã¹ã¯ãŒãã«é©çšã§ããŸãã ãã ããã»ãšãã©ã®å ŽåãããããªäŸå€ïŒ 1Password / KeePassã«ç¹ã«æè¬ïŒãé€ã ã人ã ã¯ãã¹ã¯ãŒããšããŠæåã®é åºä»ãçµã¿åãããéžæããŸã-èŸæžã®åèªãåçŽãªããŒããŒãã·ãŒã±ã³ã¹ïŒqwertyãasdfãzxcvbnãªã©ïŒãç¹°ãè¿ãïŒaaaaaaaïŒãã·ãŒã±ã³ã¹ïŒããšãã°ãabcdefãŸãã¯654321ïŒãããã³äžèšã®é ç®ã®çµã¿åããã ãã¹ã¯ãŒãã«å€§æåãå«ãŸããŠããå Žåããã®ãããªæåã¯ã»ãšãã©ã®å Žåããã¹ã¯ãŒãã®æåã®æåã«ãªããŸãã æ°åãšç¹æ®æåã®äœ¿çšããç¹ã«ãããã¯ãŒã¯å°éçšèªl33tã®äœ¿çšïŒæ°å3ãæåeã0-oã@ãŸãã¯4-aã«çœ®ãæããïŒã幎ãæ¥ä»ãéµäŸ¿çªå·ãªã©ã®äœ¿çšã«ããããã°ãã°äºæž¬å¯èœã§ãã
ãã®çµæããã¹ã¯ãŒãã®åŒ·åºŠãåæããããã®åçŽåãããæ¹æ³ã¯ä¿¡é Œã§ããŸããã äžè¬çã«äœ¿çšãããçµã¿åããã®äœ¿çšã確èªããªããšããã¹ã¯ãŒãã«æ°åãšèšå·ã䜿çšããããšãæšå¥šããŠãããããã³ã°ã¯ããã»ã©è€éã«ãªããŸããããæèšã¯ããªãè€éã«ãªããŸãã xkcdã®ã³ããã¯ã®1ã€ã¯ããã®ç¶æ³ãå®å šã«èª¬æããŠããŸãã
>
ãããã£ãŠãç§ã¯Dropboxãå®æœãã次ã®ãã¯ã©ãã«ãŒãŠã£ãŒã¯ãã®ç¬ç«ãããããžã§ã¯ããšããŠãåçŽãªçµã¿åãããé€å€ãããªãŒãã³ãœãŒã¹ã®ãã¹ã¯ãŒã匷床ã¢ãã©ã€ã¶ãŒãäœæããããšã決å®ããŸããããããã£ãŠãhorseebatterystapleïŒreturn horseïŒãªã©ã®ããªãè€éãªãã¹ãã¬ãŒãºãçŠæ¢ããŸãã ãã®ãŠãŒãã£ãªãã£ã¯çŸåšã dropbox.com / registerã§å ¥æã§ãã github ã§äœ¿çšã§ããŸã ã ãã¢çãèªåã§è©ŠããŠãããã€ãã®ãã¹ã¯ãŒããè©äŸ¡ã§ããŸãã
次ã®è¡šã§ã¯ãzxcvbnãä»ã®ãã¹ã¯ãŒã匷床ã¢ãã©ã€ã¶ãŒãšæ¯èŒããŠããŸãã æ¯èŒã®ãã€ã³ãã¯ãä»ã®ã¢ããªã±ãŒã·ã§ã³ã®å€±æã蚌æããããšã§ã¯ãããŸãã-åãµã€ãã«ã¯ç¬èªã®ãã¹ã¯ãŒãããªã·ãŒããããŸãããzxcvbnã®æ©èœãããããç解ããããã§ãã
qwER43@!
| Tr0ub4dour&3
| correcthorsebatterystaple
| |
---|---|---|---|
zxcvbn | |||
DropboxïŒå€ãïŒ | |||
ã·ãã£ãã³ã¯ | |||
ã¢ã¡ãªã«éè¡ | ç¡å¹ã§ã | ç¡å¹ã§ã | ç¡å¹ã§ã |
ãã€ãã« | |||
eBay | ç¡å¹ã§ã | ||
ãã§ã€ã¹ãã㯠| |||
Yahoo! | |||
Gmail |
ããã€ãã®ã¡ã¢ïŒ
- 2012幎4æ3æ¥ã«ãããã®ã¹ã¯ãªãŒã³ã·ã§ãããæ®ããŸããã
- Zxcvbnã¯ãcorrecthorsebatterystapleã3ã€ã®äžã§æãä¿¡é Œã§ãããã¹ã¯ãŒããšèŠãªããŸãã ä»ã®ã¢ããªã±ãŒã·ã§ã³ã¯ããããæãéå¹çã§ãããšèŠãªããããŸã£ãã䜿çšã§ããªãããã«ããŸãã ïŒTwitterã¯3ã€ã®ãã¹ã¯ãŒãã«ã»ãŒåçã®ã»ãã¥ãªãã£ãå²ãåœãŠãŸããããããèŠããšããããªéãããããŸããïŒ
- Zxcvbnã¯qwER43 @ïŒ æå·åãããQWERTYããŒããŒãã·ãŒã±ã³ã¹ã§ãããããéå¹ççãªãã¹ã¯ãŒãã ã·ã³ãã«ã®æ¹åãšã·ãããå€åãããã³ã«ããšã³ããããŒãå¢å ããŸãã
- PayPalãã¹ã¯ãŒãã¢ãã©ã€ã¶ãŒã¯qwER43ãã«ãŠã³ãããŸã@ïŒ ç¡å¹ãªãã¹ã¯ãŒãã§ãããaaAA11 !!! -ä¿¡é Œã§ããã ããŒããŒãã·ãŒã±ã³ã¹ãèªèãããšæ³å®ã§ããŸãã
- ãã³ã¯ãªãã¢ã¡ãªã«ã®ç»é²ãã©ãŒã ã§ã¯ãæ£ããhorsebatterystapleãå«ã20æåãè¶ ãããã¹ã¯ãŒãã¯èš±å¯ãããŠããŸããã ã«ãŒã«ã«åŸã£ãŠãäžéšã®ç¹æ®æåããã¹ã¯ãŒãã«äœ¿çšã§ããŸããããïŒããšãïŒãã¯ããããèš±å¯ãããŠããããæ®ãã®2ã€ã®ãã¹ã¯ãŒãã®äœ¿çšã¯çŠæ¢ãããŠããŸãã eBayã§ã¯ã20æåãè¶ ãããã¹ã¯ãŒããèš±å¯ãããŠããŸããã
- ãŸããªäŸå€ãé€ããŠããã¹ããããããã°ã©ã ã¯ç§ãšåãåºæ¬çãªåºæºã«åŸã£ãŠããªãããã§ããããã§ãªããã°ãæ£ããé·ãã®ããããªãŒã¹ããŒãã«ã¯ãã®é·ãã®ããã«æé«ã®è©äŸ¡ãåŸãŸãã Dropboxãã¹ã¯ãŒãã¢ãã©ã€ã¶ãŒã®ä»¥åã®ããŒãžã§ã³ã§ã¯ããããã®æåã°ã«ãŒãããšã«ç¹å®ã®å¶éãŸã§äœ¿çšãããå°æåã倧æåãæ°åãããã³ç¹æ®æåã®ãã¹ã¯ãŒãã«ãã€ã³ããè¿œå ãããŸããã ãã®ã¢ãããŒãã¯åŸ¹åºçãªæ€çŽ¢ã«ããæ»æããã®ã¿ä¿è·ããŸããããã®ã·ã¹ãã ã«ã¯æãäžè¬çãªåèªã®èŸæžã䜿çšããŠæ°ãããã¹ã¯ãŒãããã§ãã¯ãããªãã·ã§ã³ããããŸãã ãã¹ããããæ®ãã®ããã°ã©ã ã®åäœåçã¯ããããŸããããéçºè ã¯ãã®ãããªä¿¡é Œæ§åºæºããŒãã«ãé©çšããããšããããããŸãïŒãã ããå°æ°ã®çµã¿åããã䜿çšããŠãã¹ã¯ãŒããæ€èšŒããŸãïŒã
- 2åç®ã®åºæ¬ãã¹ã¯ãŒãã®åèªã«ã€ããŠã¯ãxkcdã®ããã«ããã«ãããŒã«ã§ã¯ãªãããã«ãããŒã«ã䜿çšããŸããïŒæåŸã®ã¹ãã«ã¯ãŸãã§ãïŒã
èšçœ®
zxcvbnã·ã¹ãã ã¯ãã©ãŠã¶ã®çš®é¡ã«å¶éããããInternet ExplorerïŒããŒãžã§ã³7以éïŒ/ Opera / FireFox / Safari / Google Chromeã§åäœããŸãã ç»é²ããŒãžã«è¿œå ããæãç°¡åãªæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
<script src="zxcvbn-async.js" type="text/javascript"> </script>
zxcvbn-async.jsã¹ã¯ãªããã®ãµã€ãºã¯ããã350ãã€ãã§ãã window.loadãå®è¡ããåŸãããŒãžãããŒããããŠè¡šç€ºããããšãzxcvbn.jsãããŒããéå§ããŸã-680 Kãã€ãïŒãŸãã¯gzipã§320 Kãã€ãïŒã®ãéãããã¡ã€ã«ã§ããã®ã»ãšãã©ã¯èŸæžã§ãã ã¹ã¯ãªãããµã€ãºãåé¡ãåŒãèµ·ããã®ãèŠãããšã¯ãããŸããããŠãŒã¶ãŒã¯éåžžããã¹ã¯ãŒããéžæããåã«ä»ã®ããŒã¿ãç»é²ãã©ãŒã ã«å ¥åãããããã¹ã¯ãªãããããŒãããã®ã«ååãªæéããããŸãã ããŸããŸãªãã©ãŠã¶ãŒã§ã®éåæã¹ã¯ãªããã®èªã¿èŸŒã¿ã®å®å šãªèª¬æã次ã«ç€ºããŸãã
Zxcvbnã¯ãã°ããŒãã«åå空éã«1ã€ã®é¢æ°ãè¿œå ããŸãã
zxcvbn(password, user_inputs)
å¿ é ã®åŒæ°ïŒãã¹ã¯ãŒãïŒã1ã€åãåãã次ã®ããããã£ãæã€çµæãªããžã§ã¯ããè¿ããŸãã
result.entropy # result.crack_time # (.) result.crack_time_display # , : # «», «6 », «» . . result.score # , 0, 1, 2, 3 4, # 10**2, 10**4, 10**6, # 10**8 , . # ( ) result.match_sequence # , # result.calculation_time # ();
ãªãã·ã§ã³ã®user_inputsåŒæ°ã¯ãzxcvbnãçµã¿èŸŒã¿èŸæžã«è¿œå ããæååã®é åã§ãã çè«çã«ã¯ãä»»æã®è¡ãå«ããããšãã§ããŸãããããã¯ãŠãŒã¶ãŒããã©ãŒã ã®ä»ã®ãã£ãŒã«ãïŒããšãã°ãååãé»åã¡ãŒã«ã¢ãã¬ã¹ïŒã«å ¥åããããŒã¿ã§ãããšæ³å®ãããŸãã ãããã£ãŠãå人ãŠãŒã¶ãŒããŒã¿ãå«ããã¹ã¯ãŒãã®åŒ·åºŠã¯éåžžã«äœãè©äŸ¡ã§ããŸãã ãã®ãªã¹ãã¯ãç¹å®ã®ãµã€ãã®ç¹å¥ãªèŸæžã®äŒèšã«ã䟿å©ã§ãïŒããšãã°ãç§ã®ããã°ã©ã ã¯Dropboxãµã€ãã®ç¹å®ã®èŸæžãèæ ®ããŸãïŒã
zxcvbnããã°ã©ã ã¯CoffeeScriptã§æžãããŠããŸãã zxcvbn.jsããã³zxcvbn-async.jsãã¡ã€ã«ã¯ã¯ããŒãžã£ãŒã³ã³ããŒã¿ãŒã«ãã£ãŠåŠçãããŸããããzxcvbnãæ¹åãããå Žåã¯ããã«ãªã¯ãšã¹ããéä¿¡ããŠãã ãããREADME ãã¡ã€ã«ã«ã¯ãéçºç°å¢ã®ã€ã³ã¹ããŒã«ã«é¢ããæ å ±ãå«ãŸããŠããŸãã
ããã¹ãã«æ²¿ã£ãŠãzxcvbnã®åäœåçã詳现ã«èª¬æããŸãã
ã¢ãã«
Zxcvbnã¯ãäžèŽïŒèª¿æŽïŒãã¹ã³ã¢ïŒèšç®ïŒãæ€çŽ¢ïŒæ€çŽ¢ïŒã®3段éã§åäœããŸãã
- äžèŽé¢æ°ã¯ãæ¢ç¥ã®ãã¹ãŠã®çµã¿åããïŒäº€å·®ããçµã¿åãããå«ãïŒã調æŽããŸãã çŸåšãzxcvbnã¯ãããã€ãã®èŸæžïŒè±èªã®åèªãååãå§ã®èŸæžãããã³10,000ã®æãäžè¬çãªBurnettãã¹ã¯ãŒãã®ãªã¹ãïŒãé£ç¶ããããŒã®çµã¿åããïŒQWERTYãDvorakããã³ããžã¿ã«ïŒãç¹°ãè¿ãïŒaaaïŒãæ°åããã³æåã·ãŒã±ã³ã¹ïŒ 123ãgfedcbaïŒã1900幎ãã2019幎ãŸã§ã®æéãæ¥ä»ïŒåœ¢åŒ3-13-1997ã13.3.1997ã1331997ïŒã ãã¹ãŠã®èŸæžã¯ã倧æåãšäžè¬çãªl33tã®åçç©ãèªèããŸãã
- ã¹ã³ã¢é¢æ°ã¯ãäžèŽããåçµã¿åããã®ãšã³ããããŒã®åºŠåããããã¹ã¯ãŒãã®æ®ãã®éšåãšã¯å¥ã«èšç®ããŸãïŒã¯ã©ãã«ãŒããã®çµã¿åãããç¥ã£ãŠãããšä»®å®ïŒã ç°¡åãªäŸã¯rrrrrã§ãã ãã®å Žåãã¯ã©ãã«ãŒã¯å°æåã§å§ãŸã1ãã5ãŸã§ã®ãã¹ãŠã®ç¹°ãè¿ããªãã·ã§ã³ãå®è¡ããå¿ èŠããããŸãã
entropy = lg(26*5) # 7
- æ€çŽ¢æ©èœã¯ãOccamã«ããœãªã®åçã䜿çšããŠããŸãã å¯èœãªéè€äžèŽã®å®å šãªã»ãããããæ€çŽ¢ã¯åçŽãªäºãã«çŽ ãªã·ãŒã±ã³ã¹ãçæããŸãïŒãšã³ããããŒãæå°ïŒã ããšãã°ããã¹ã¯ãŒãããã ããŒã·ã§ã³ã®å Žåããã ãšããŒã·ã§ã³ãšãã2ã€ã®åèªã«åãããã1ã€ã®åèªãšèŠãªãããšãã§ããŸãã ãã®å Žåãåèªå šäœãæ€èšããããšãéèŠã§ããåèªãæ€çŽ¢ããã¯ã©ãã«ãŒã¯ã2åèªãããã¯ããã«é«éã«1åèªãšããŠãã¹ã¯ãŒããéžæããããã§ãã ãšããã§ã亀差ããçµã¿åããã¯ãŸããchildrens-laughter.comã®ãããªæå³ããªãèŽåœçãªãã¡ã€ã³åã®åºçŸã®äž»ãªçç±ã§ããããã€ãã³ã¯ãããŸããïŒçŽïŒåã©ãã®ç¬ã-åã©ãã®ç¬ã声ãåã©ãã®ç¬ã声-幌å 殺人ïŒã
æ€çŽ¢æ©èœã¯ãã¢ãã«ã®åºç€ã§ãã ç§ã¯åœŒå¥³ããå§ããŠæåã«æ»ããŸãã
ãšã³ããããŒæå°æ€çŽ¢
Zxcvbnã¯ããã¹ã¯ãŒãã®ãšã³ããããŒã®åºŠåããããã®æ§æéšåã®ãšã³ããããŒã®åèšãšããŠèšç®ããŸãã èå¥ãããçµã¿åããéã®ãã¹ã¯ãŒãã®ä»»æã®éšåã¯ãç¬èªã®ãšã³ããããŒãæã€ãã«ãŒããã©ãŒã¹æšæž¬ã·ãŒã±ã³ã¹ãšèŠãªãããŸãã å§ã®ãšã³ããããŒãåæã®ãšã³ããããŒãããŒããŒãã®ãšã³ããããŒã§æ§æããããšã³ããããŒã®äŸã次ã«ç€ºããŸãã
entropy("stockwell4$eR123698745") == surname_entropy("stockwell") + bruteforce_entropy("4$eR") + keypad_entropy("123698745")
ããã§ã¯ããã¹ã¯ãŒãã®ãšã³ããããŒã¯ãã®éšåã®ãšã³ããããŒã®åèšã§ãããšããé倧ãªä»®å®ãç«ãŠãŸãã ãã ãããã®ä»®å®ã¯éåžžã«ä¿å®çã§ãã ãæ§æã®ãšã³ããããŒããã€ãŸããã¹ã¯ãŒãã®äžéšã®æ°ãšé 眮ã®ãšã³ããããŒãèæ ®ããã«ãzxcvbnã¯ãã¹ã¯ãŒãæ§é ã«å€ãå²ãåœãŠãã«æå³çã«åèšãšã³ããããŒãéå°è©äŸ¡ããŸããããã°ã©ã ã¯ãã¯ã©ãã«ãŒããã§ã«ãã¹ã¯ãŒãæ§é ãç¥ã£ãŠãããšä»®å®ããŸãïŒããšãã°ããå§éžæã®çµã¿åãããæ°åãïŒãããã³ãã¹ã¯ãŒãé ç®ãæšæž¬ããè©Šè¡åæ°ã®ã¿ãèšç®ãããŸãã ãããã£ãŠãè€éãªæ§é ãæã€ãã¹ã¯ãŒãã®ãšã³ããããŒã¯å€§ããéå°è©äŸ¡ãããŸãã æ£ããhorsebatterystapleïŒåèª-åèª-åèª-åèª-åèªïŒã®ãã¹ã¯ãŒãã解èªããããšã«ãããL0phtCrackãJohn the Ripperãªã©ã®ããã°ã©ã ã䜿çšããã¯ã©ãã«ãŒã¯ãååãšããŠãæåã«å€ãã®åçŽãªæ§é ïŒåèªãåèªçªå·ãåèª-åèªïŒã«å°éãããŸã§ééããŸãåèª-åèª-åèª-åèªã ãã ãããã®ããã°ã©ã ã®æ¬ åŠãæ°ã«ãªããªãçç±ã¯3ã€ãããŸãã
- æ§é ãšã³ããããŒã®åªããã¢ãã«ãéçºããããšã¯ããã»ã©åçŽã§ã¯ãããŸããã ãŠãŒã¶ãŒãæãé »ç¹ã«äœ¿çšããæ§é ã«é¢ããçµ±èšæ å ±ã¯ãããŸããããã®ãããæ£ç¢ºãã®ããã«ããã¹ã¯ãŒããšã³ããããŒã®æšå®å€ãéå°è©äŸ¡ããæ¹ãé©åã§ãã
- è€éãªãã¹ã¯ãŒãæ§é ã§ã¯ãå€ãã®å Žåããã®éšåã®ãšã³ããããŒã®åèšã«ãããåªããè€é床è©äŸ¡ããã§ã«æäŸãããŠããŸãã ããšãã°ãæ£ããhorsebatterystapleãã¹ã¯ãŒãã®ãã¹ã¯ãŒã-åèª-åèª-åèªã®æ§é ãç¥ã£ãŠããŠããã¯ã©ãã«ãŒã¯äœäžçŽã«ãããã£ãŠãã®ãã¹ã¯ãŒãã解èªããŸãã
- ã»ãšãã©ã®äººã¯ããã¹ã¯ãŒããäœæãããšãã«è€éãªæ§é ã䜿çšããŸããã ååãšããŠãæ§é ãç¡èŠãããšãåèšãšã³ããããŒãæ°ãããã ãæžå°ããŸãã
ãã®ä»®å®ãç解ããã®ã§ãCoffeeScriptã®å¹ççãªåçã¢ã«ãŽãªãºã ãèŠãŠã¿ãŸããããããã«ãããäžèŽããæå°ã®äºãã«çŽ ãªã·ãŒã±ã³ã¹ãèŠã€ããããšãã§ããŸãã é·ãnã®ãã¹ã¯ãŒãã®å Žåããã®äœæ¥æéã¯OïŒnâ¢mïŒã§ãããèšå·ã®çµã¿åããïŒäº€å·®ãããã®ãå«ãïŒã®måã®äžèŽãå«ãã
# : , # (match.i) # (match.j) , minimum_entropy_match_sequence = (password, matches) -> # , 26 â , bruteforce_cardinality = calc_bruteforce_cardinality password up_to_k = [] # k, backpointers = [] # k, # (match.j = k). # , for k in [0...password.length] # : # # k-1. up_to_k[k] = (up_to_k[k-1] or 0) + lg bruteforce_cardinality backpointers[k] = null for match in matches when match.j = k [i, j] = [match.i, match.j] # , i-1 + # j candidate_entropy = (up_to_k[i-1] or 0) + calc_entropy(match) if candidate_entropy < up_to_k[j] up_to_k[j] = candidate_entropy backpointers[j] = match # , match_sequence = [] k = password.length â 1 while k >= 0 match = backpointers[k] if match match_sequence.push match k = match.i â 1 else k -= 1 match_sequence.reverse() # «» , # # : # 1.j = 2.i â 1 1, # 2. make_bruteforce_match = (i, j) -> pattern: 'bruteforce' i: i j: j token: password[i..j] entropy: lg Math.pow(bruteforce_cardinality, j â i + 1) cardinality: bruteforce_cardinality k = 0 match_sequence_copy = [] for match in match_sequence # [i, j] = [match.i, match.j] if i â k > 0 match_sequence_copy.push make_bruteforce_match(k, i â 1) k = j + 1 match_sequence_copy.push match if k < password.length # «» match_sequence_copy.push make_bruteforce_match(k, password.length â 1) match_sequence = match_sequence_copy # â « » min_entropy = up_to_k[password.length - 1] or 0 crack_time = entropy_to_crack_time min_entropy # password: password entropy: round_to_x_digits min_entropy, 3 match_sequence: match_sequence crack_time: round_to_x_digits crack_time, 3 crack_time_display: display_time crack_time score: crack_time_to_score crack_time
ããã¯ãã€ã³ã¿ãŒ[j]é åã«ã¯ããã¹ã¯ãŒãäœçœ®jã§çµããã·ãŒã±ã³ã¹ã®äžèŽãæ ŒçŽãããŸããã·ãŒã±ã³ã¹ã«ãã®ãããªäžèŽããªãå Žåã¯nullãæ ŒçŽãããŸãã åçããã°ã©ãã³ã°ã§ã¯ãæé©ãªã·ãŒã±ã³ã¹ã®æ§ç¯ã¯éåžžãæåŸããéå§ãããå察æ¹åã«ç§»åããŸãã
ãã®ã¹ã¯ãªããã¯ããã¹ã¯ãŒãå ¥åæã«ãã©ãŠã¶ã§æ©èœãããããããã©ãŒãã³ã¹ã¯ç¹ã«éèŠã§ãã ããã°ã©ã ãæ©èœãããããã«ãå¯èœæ§ã®ãããã¹ãŠã®ç¬ç«ãããµãã»ããã®åèšãèšç®ããåçŽãªOïŒ2 m ïŒã¢ãããŒãããå§ããåé¡ã®è€éãã«ããããã»ã¹ãéåžžã«éãã¹ããŒããŠã³ããŸããã çŸåšãã»ãšãã©ã®ãã¹ã¯ãŒããå®å šã«åæããããã«ãzxcvbnã¯æ°ããªç§ããããããŸããã æã倧ãŸããªæšå®ã«ãããšã2.4 GHz Intel Xeonã®Google Chromeã§ã¯ãæ£ããhorsebatterystapleãã¹ã¯ãŒãã¯å¹³åçŽ3ããªç§ã§åæãããŸãã ãã¹ã¯ãŒãcoRrecth0rseba ++ ery9 / 23 / 2007staple $ã¯ãå¹³åã§çŽ12ããªç§ããããŸãã
è åšã¢ãã«ïŒãšã³ããããŒãšç Žå£æéã®çžé¢
ãšã³ããããŒã®æŠå¿µã¯ããŸãéæãªææšã§ã¯ãããŸããã 28ãããã®ãã¹ã¯ãŒãã§ååãã©ãããç解ããæ¹æ³ã¯ïŒ èšãæãããšããšã³ããããŒã®æšå®ããçŽæ¥ãããã³ã°ã®æéã«é²ãæ¹æ³ã¯ïŒ ããã«ã¯è åšã¢ãã«ã䜿çšãããŸãã 次ã®ããã«ä»®å®ããŸãã
- ãã¹ã¯ãŒãã¯ããã·ã¥åœ¢åŒã§ä¿åãããåãŠãŒã¶ãŒã®ãå¡©ããšãå¡©ããã©ã³ãã ã«éžæããããããã¬ã€ã³ããŒããŒãã«ã䜿çšããæ»æãäžé©åã«ãªããŸãã
- ã¯ã©ãã«ãŒã¯ãã¹ãŠã®ããã·ã¥ãšãã¹ãŠã®ãå¡©ãããªããšãçã¿ããã¹ã¯ãŒããå¯èœãªéãé«éã§ãªãã©ã€ã³ã§ååŸããŸããã
- ã¯ã©ãã«ãŒã«ã¯ããã€ãã®ããã»ããµããããŸãã
ããã€ãã®ææšå³ïŒ
# -, bcrypt/scrypt/PBKDF2, # 10 . # â , # # ; # - , # â , ! SINGLE_GUESS = .010 # NUM_ATTACKERS = 100 # SECONDS_PER_GUESS = SINGLE_GUESS / NUM_ATTACKERS entropy_to_crack_time = (entropy) -> .5 * Math.pow(2, entropy) * SECONDS_PER_GUESS
ããã§ã0.5ã®ä¿æ°ãå ¥åããŸãããããã¯ãæ€çŽ¢ã¹ããŒã¹å šäœãå埩ããæéã§ã¯ãªããå¹³åã®ãããã³ã°æéãèšç®ããããã§ãã
ããããããããã®èšç®ã¯ä¿å®çãããŸãã 倧èŠæš¡ãªããã·ã¥çªçã¯ãã£ãã«èµ·ãããŸãããæ»æãçŽæ¥ããªãã«åããããŠããªãéããã¯ã©ãã«ãŒã¯1ã€ã®ãã¹ã¯ãŒãã«100ã³ã¢ã䜿çšããããšã¯ã»ãšãã©ãããŸããã éåžžãæ»æè ã¯ãªã³ã©ã€ã³ã§æšæž¬ããå¿ èŠãããããããã¯ãŒã¯ã®é 延ãé 延ã®å¢å ãCAPTCHAã«æ©ãŸãããŠããŸãã
ãšã³ããããŒèšç®
次ã«ãzxcvbnããã¹ã¯ãŒãå ã®åæåã®çµã¿åããã®ãšã³ããããŒãèšç®ããæ¹æ³ãæ€èšããŸãã ãšã³ããªãã€ã³ãã¯calc_entropyïŒïŒã§ãã ããã¯ç°¡åãªéžæã§ãïŒ
calc_entropy = (match) -> return match.entropy if match.entropy? entropy_func = switch match.pattern when 'repeat' then repeat_entropy when 'sequence' then sequence_entropy when 'digits' then digits_entropy when 'year' then year_entropy when 'date' then date_entropy when 'spatial' then spatial_entropy when 'dictionary' then dictionary_entropy match.entropy = entropy_func match
äžèšã§ã¯ãrepeat_entropyé¢æ°ãã©ã®ããã«æ©èœããããæŠèª¬ããŸããã ãšã³ããããŒèšç®ã³ãŒãã®å šæ㯠githubã§èŠã€ããããšãã§ããŸããããããç解ããããã«ãspatial_entropyïŒããŒããŒãã®çµã¿åããã®ãšã³ããããŒïŒãšdictionary_entropyïŒèŸæžãšã³ããããŒïŒã®2ã€ã®èšç®é¢æ°ã«ã€ããŠèª¬æããŸãã
qwertyhnmããŒããŒãã·ã§ãŒãã«ãããæ€èšããŠãã ããã qæåã§å§ãŸããé·ãã¯9æåã§ã3ã€ã®ç§»åæ¹åããããŸããæåã«å³ã«ç§»åãã次ã«å³äžã«ç§»åãã次ã«å³äžã«ç§»åããŸãã ãã®çµã¿åããããã©ã¡ãŒã¿ãŒåããŸãã
s # # 47 â QWERTY/Dvorak, 15 â PC 16 â # Macintosh L # ; L >= 2 t # ; t <= L â 1 # , 3 2 («qaw») d # «» ; # QWERTY/Dvorak 4,6 ( g â 6 , # â 1)
次ã«ãå¯èœæ§ã®äžè¬çãªã¹ããŒã¹ã«ã¯ãé·ãL以äžã®ãã¹ãŠã®å¯èœãªããŒããŒãã®çµã¿åãããå«ãŸããæ¹åã®å€æŽã¯t以äžã§ãïŒ
é¢æ°ã ïŒi-1ïŒããïŒj-1ïŒãžã®äºé ä¿æ° ãã¯ãjæ¹åãå€åããé·ãiã®ããŒããŒãã®çµã¿åããã®æ¹åãå€æŽããããã®å¯èœãªæ§æãèšç®ããŸãã æ¹åã®æåã®å€æŽã¯åžžã«æåã®æåã§çºçãããããäž¡æ¹ã®èŠçŽ ã«ã-1ããè¿œå ãããŸãã jæ¹åã®å€åã®ããããã«ã€ããŠãdã®å¯èœãªæ¹åãã€ãŸããåæ§æã®djã®å¯èœæ§ã®åèšããããŸãã ãŸããã¯ã©ãã«ãŒã¯ãã¹ãŠã®åææåãå埩åŠçããå¿ èŠããããããåŒã®ä¿æ°ã¯sã§ãã æ°åŒèªäœã¯éåžžã«è¿äŒŒã§ã-ç¹ã«èæ ®ãããŠãããªãã·ã§ã³ã®å€ãã¯å®éã®ããŒããŒãã§ã¯äžå¯èœã§ããããã§ãïŒããŒããŒãã®é·ã5ãšæ¹åã®å€æŽ1ã®çµã¿åããã§ã¯ããã§å§ãŸãããå·Šã«ç§»åããšããæäœãèæ ®ãããŸãããäžå¯èœã§ãã
ãã®CoffeeScriptåŒã¯æ¬¡ã®ããã«èšè¿°ã§ããŸãã
lg = (n) -> Math.log(n) / Math.log(2) nPk = (n, k) -> return 0 if k > n result = 1 result *= m for m in [n-k+1..n] result nCk = (n, k) -> return 1 if k = 0 k_fact = 1 k_fact *= m for m in [1..k] nPk(n, k) / k_fact spatial_entropy = (match) -> if match.graph in ['qwerty', 'dvorak'] s = KEYBOARD_STARTING_POSITIONS d = KEYBOARD_AVERAGE_DEGREE else s = KEYPAD_STARTING_POSITIONS d = KEYPAD_AVERAGE_DEGREE possibilities = 0 L = match.token.length t = match.turns # L, t for i in [2..L] possible_turns = Math.min(t, i â 1) for j in [1..possible_turns] possibilities += nCk(i â 1, j â 1) * s * Math.pow(d, j) entropy = lg possibilities # , # (% 5, A a) # , # # . . if match.shifted_count S = match.shifted_count U = match.token.length â match.shifted_count # possibilities = 0 possibilities += nCk(S + U, i) for i in [0..Math.min(S, U)] entropy += lg possibilities entropy
:
dictionary_entropy = (match) -> entropy = lg match.rank entropy += extra_uppercasing_entropy match entropy += extra_l33t_entropy match entropy
â : : , the good , photojournalist maelstrom â . zxcvbn , , , . , correcthorsebatterystaple xkcd zxcvbn (45,2 44 ). xkcd 211 ( 2000 ), zxcvbn . zxcvbn.js , , , .
, «», , . , , :
extra_uppercase_entropy = (match) -> word = match.token return 0 if word.match ALL_LOWER # â # , # ( + # ): # 1 . # # , # , , # , 1 for regex in [START_UPPER, END_UPPER, ALL_UPPER] return 1 if word.match regex # , # # U+L U # , , (, PASSwORD), â # U+L L U = (chr for chr in word.split(â) when chr.match /[AZ]/).length L = (chr for chr in word.split(â) when chr.match /[az]/).length possibilities = 0 possibilities += nCk(U + L, i) for i in [0..Math.min(U, L)] lg possibilities
, 1 « » . , :
l33t , .
, , zxcvbn . â : :
dictionary_match = (password, ranked_dict) -> result = [] len = password.length password_lower = password.toLowerCase() for i in [0...len] for j in [i...len] if password_lower[i..j] of ranked_dict word = password_lower[i..j] rank = ranked_dict[word] result.push( pattern: 'dictionary' i: i j: j token: password[i..j] matched_word: word rank: rank ) result
Ranked_dict . , , . l33t , dictionary_match. (, bvcxz) , . . matching.coffee github .
, 10 000 , 2011 .
2000 , . zxcvbn Internet Explorer 7, 80 % (. . 80 % , ), â 90 %.
40 000 Wiktionary , 29 . , . , , , (, ), â . , , Frasier 824- .
ãããã«
, , . , â , « » , ( ) . , , . : , , , ( , ).
, . Zxcvbn , ; n-; ; (, qzwxec) . (, ) , , zxcvbn, , â . :
- zxcvbn , . . zxcvbn . .
- , , . zxcvbn , « » , . n- Google , , . , Google.
- Zxcvbn ( ) . ( , ). , â , l33t.
, , , zxcvbn , . , . «» github !
, , , , , , , , , , , , , , .
ABBYY Language Services
ps « », « » â .