aku*_*zma 2 java spring vaadin
我在我的项目中使用了vaadin,spring和jpa.我需要检查并告知用户他的密码有多强,并希望在纯java中执行此操作.
你能推荐我最好的方法吗?如果密码至少有一个数字等,使用特殊库或只检查正则表达式会更好吗?您如何看待?
如果你有这个和良好的图书馆或教程的任何链接,请发送给我.
一般来说,某人密码的强度取决于它的可猜测程度.更复杂的密码不太可猜测.您可以通过将字典攻击或暴力算法猜测密码的可能性与其相关联来估计复杂性.一旦验证密码不是常见密码,您可以根据使用强力猜测密码所花费的时间来估计其复杂程度.从这个意义上讲,您可以测量类似随机密码的熵的二进制位数.这可以粗略估计其可猜测性,尽管一位评论者指出,测量复杂性很困难.在我拍摄的一个安全类中,教师建议人们应该瞄准至少40位熵,但60被认为是安全的(假设密码不能与随机选择的密码区分开).因此,密码计的工作是猜测等效随机密码的熵.显然,这里存在很多陷阱,使用已建立的库可以为您节省大量时间.
每个字符的熵是log10(number_possible_characters)/ log10(2),因此您可以将熵计算为pwd.length() * Math.log10(numPossibleCharacters)/Math.log10(2)- 并且使用26个字符,即每个字符大约4.7位熵.
以纯粹科学的方式测量熵并不总是对可猜测性的有效估计,因为密码"abc123"可能看起来与"j3s9fn"一样好(对于计算机,而不是人类),但人类可以很容易地看到第一个比第二个猜测更容易被猜到.严格来说,熵是衡量真实随机性的标准; 虽然我们知道人类不是随机的,但它们可能足够接近随机,我们测量熵作为替代,并希望我们的算法测量人类产生的随机性/创造性/不可思议性的类型.因此,这既是技术问题,也是人类行为问题.
如果我没记错的话,我曾经被告知,英文散文(页面上的文字)每个字符只有大约1.5位的熵 - 换句话说,它更容易预测,所以你需要大约3倍的如果你只输入英文单词,那么它的密码是"强"的,而不是你输入随机小写的乱码.坦率地说,我认为REQUIRE符号/数字/大写的密码系统是愚蠢的,因此:如果我愿意,我应该能够输入更多的散文.因人而异.
我们应该通过估计用户可以为他们键入的每个字符选择或可能选择的字符数来开始测量熵.
可能的字符numPossibleCharacters数基于用户似乎使用的字符集或允许他们使用的字符集.例如,如果用户键入,abc那么您将假设他们只选择26个可能的字符(每个字符4.7个).但是,如果他们输入,aBc你会假设他们选择了52(小写和大写)(每个字符5.7).如果他们使用数字,则添加另外10个可能的字符(除非他们似乎只选择明显的数字).
此外,添加数字作为事后补充的用户倾向于将它们放在密码的开头或结尾.因此,他们更改字符集的次数也可能是密码强度的一个很好的衡量标准.例如,"word908"明显不如"w39or7d"安全.当你这样做时,你走出简单的复杂性估计.
如果你使用这种更为宽松的复杂性定义,那么测量密码被任何类型的攻击猜测的可能性要困难得多,尽管你可能会尝试想象一种选择半随机密码的智能攻击,从最可猜测的开始最有可能的模式.你可能会说每个字符增加的复杂性(熵?)取决于它是否与前一个字符在同一个字符集中,是否与前一个字符相同,或者它是否重复了一些明显的模式(如"123"或"ABC").
您可能会说从一组字符到另一组字符的每个切换(小写到高位,或数字到符号)本身就是一个随机事件.假设我们定义了5个字符集:小写,大写,数字,common_symbols和uncommon_symbols.我们检测到有多少这些集合正在使用中(例如,如果用户输入'123abc' charSetsUsed则为2).然后,我们一次循环一个字符串中的字符.每次用户更改字符集时,我们都会这样说entropy += log(charSetsUsed)/log(2).然后,对于每个角色,我们也添加entropy += log(charsInThisCharSet)/log(2).[编辑:这不是真正的熵,所以也许你应该把它看作估计的复杂性]
如果您真的想获得技术,可以测量字符集更改的数量.假设密码长度为10个字符.它可以有1到9个设置更改,这是10个选项.然后我们说它们是作为插槽的组合分发的.所以我们这样做:
log(numChanges)/log(2) + log(combination(totalSlots, usedSlots))/log(2).
Run Code Online (Sandbox Code Playgroud)
假设用户输入aoq35esm42.我们看到他们从一个字符集切换到另一个字符集的3个地方.这是一个10个字符的密码,因此设置更改有9个可能的位置(两个字符中的任何一个之间出现位置),它们的顺序无关紧要(因此组合/二项式系数/ n选择r):
log(numChanges)/log(2) + log(combination(9, 3))/log(2).
log(3 )/log(2) + log( 84 )/log(2).
1.5849625 + 6.3
7.97727992
Run Code Online (Sandbox Code Playgroud)
所以我们看到我们有几乎8位的熵基本上说"在他们可以选择改变字符集的所有地方和时间中,有大约8个随机位或者它们可以在这里做的2 ^ 8种可能性".如果我们然后根据每个字符的子集计算每个字符的熵,并选择每个变化使用的子集,那么我们可能会像这样添加熵(如果我在数学上犯了错误,请纠正我):
使用apache commons MathUtils.binomialCoefficientDouble()函数计算组合.
此外,如果密码包含字典单词,则认为密码较弱.因此,如果您可以扫描字典,您可以假设(猜测)这些字符应该被测量为英文散文,每个字符有1.5位熵.但是,您不希望将密码暴露给数据库查询(可能会记录在哪里),所以最好的办法是猜测是否有英文单词(祝你好运),就像假设(相当糟糕)任何一组包含元音的3-5个单个字母的字母字符是英文单词.或者,您可以构建一个最常见的英语音节字典,这可能更容易存储在内存中.或者,您可以放弃并假设您的用户无论如何都会对系统进行游戏,以使其密码更加难忘.
尽管如此,如果您确定准确,您可以在安全存储器中存储英语单词的内存数据库.
所有这些加起来相当复杂的算法仍然可能是不完整的.您可能应该使用相对简单的计算,或使用其他人已编写的库.
''安全存储''
计算密码安全性的方法实际上并不能解决一个完全不同的问题:在密码通过网络或客户端内存时保持密码安全.我不是这里的专家,但我读得足以知道要小心并做我的作业.至少,我会使用https并强烈考虑使用浏览器的本机密码输入字段.这是避免滚动自己的技术,而是使用图书馆的另一个原因(只要你可以告诉他们做了比你能管理的更多的功课;我不知道我相信技术,除非我是看着它).此外,您绝不应以明文形式存储密码,而应使用单向加密/散列.给你的密码加盐,然后使用安全散列算法(不是MD5;或者更喜欢SHA2?)对它们进行哈希处理,可能会多次重新进行重新加沙和重新加盐(以增加字典攻击的成本).通常有一些库可以为您处理这类事情,即使它们没有测量密码强度; 我知道C#或.NET有专门针对salting,散列和迭代的库; 我可能还有其他一些问题 - 请记住密码强度只是安全链中的一个链接.
| 归档时间: |
|
| 查看次数: |
2119 次 |
| 最近记录: |