您的位置:首页 > Web前端 > JavaScript

个人写的测试密码强度的方法

2008-10-07 16:08 197 查看
    前两天在博客里看到有位老兄用jsp写了个测试密码强度的脚本,但是我觉得没必要像他脚本里写得那么麻烦,在加上我一时手痒(这个也许是主要原因:P),所以就禁不住用C也写了个测试密码强度的程序。

    在开始讲我的方法之前,先看看几个弱密码。第一个:123456,这个恐怕是最白痴的密码了,呵呵。第二个:19830321,很明显这是用生日来做密码。第三个:abcdefgh ,不多说了,也是个弱密码。第四个:johnabruzz(《越狱》里面那个黑帮老大的名字),这是用人名来做密码。原则上这样的密码本身的强度其实并不弱,但是对于跟你关系很亲近的人,那就不一定了。

    不知大家看出些什么规律来没有,我就不卖官子了。前三个密码中,每个字符与其前后两个字符是相临的。而这正好是破解软件和破解者最喜欢的,简单啊,估计现在没人用这样的密码了。但是这却给了我一个提示,在散列算法中有一个计算散列地址的方法,它使散列空间中的记录能够平均分布,从而降低散列冲突的概率。如果我们用这种方法,把密码中每个字符的ASCII码值一次存放到一个数组里,然后计算相临元素的差值(第一个元素和最后一个元素做差)的绝对值。第一个元素和最后一个元素的差值用密码的长度减1来使其平均化,因为如果第一个元素和最后一个元素的差值过大,就会影响估计结果。最后,将这些差值求和并求平均值。

    求完平均值后,还没完,我们得看看密码长度。如果密码的长度小于6,那么该密码就是个弱密码,不管它的平均值有多大。因为密码长度小于等于6的话,计算机可尝试的密码组合就是ASCII码的字符个数(标准的是128个)的6次幂约4398亿个组合。别看4398亿这个数字对于你来说很大,但是现在的机器,运行速度那都是钢钢的(包括赛扬),如果破解程序再用上优化算法,最多几分钟就给你破解出来。后果我就不说了。

    好了让我们用上面的方法来试试,假设弱密码的均值范围是[0,5],中等强度密码的均值范围是(5,10],强密码的均值范围是(10,+∞]。我们先看第一个弱密码:123456,他们的ASCII是相临的,于是他们的差值的平均值/强度值就是1,非常地弱。第二个密码:19830321,它的强度值是3,也很弱,可见用生日做密码一点也不好。第三个密码:abcdefgh,和第一个密码一样,强度值是1,啥也不说了,唉。那么我们换个强壮一点的密码试试,就试试我的英文名字John Adams吧,它的强度值是7,看来用人名做密码也不是多好。那么用这个变态的密码 fhgBD^*Jk*( 试试,强度值是23,不愧是变态密码,嘿嘿。

    当然这样的方法还并不完美,因为它不会判断密码是不是生日、人名等信息。我们可以用正则表达式先对密码进行一下判断然后再做进一步的计算。还有就是没有提供unicode字符的支持,但是我想这应该不难改进,就算是留了个小作业吧:P。总之,看似复杂的问题,其实可以简单化的,呵呵。

    最后,附上我用VC写得测试代码,是个控制台程序,因为本人还不是太会做GUI界面的程序,呵呵。因为本人比较懒惰,就限制了一下密码的长度为20位。代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

int GetRobustnessValue(const char* s)

{

    int  len;  //Length of the input password

    int  Robustness; //Local variable used to store password Robustness

    Robustness = 0;

    len = strlen(s);

    int i;

    int j = len - 1;

    for(i = 0; i < j; i++)

    {

        Robustness += abs((short)s[i%len] - (short)s[(i+1)%len]);

    }

    Robustness += abs(((short)s[len] - (short)s[0])/(len -1));

    return Robustness/len;

}

void main(int argc, char *argv)

{

    int Robustness;

    char c[21];

    short len;

    do{

        printf("/n/n");

        printf("please type in the test password, type /"exit/" to exit/n");

        printf("(max length is 20):");

        scanf("%s", &c); //get the password string

        len = strlen(c); //get the length of the password

        if(len > 20)  //length out of the range, so the password

        {     //is invalid

  

            printf("Invalid pasword");

            scanf("%d", &Robustness);

            exit(1);

        }

        if(len < 7)   //If the length is less of 6, then the

        {     //password is definitely weak

            printf("Week password cos it's length is short of 6");

        }

        strongth = GetRobustnessValue(c); //Get password strongth value

                                          //note: the array c passed to

                                          //      function GetRobustnessValue

                                          //      will degradated to a pointer

        printf("/n");

        printf("The password Robustness is:%d/n", Robustness);

        if((0 <= Robustness) &&(Robustness <= 5))

            printf("Very weak password!");

        if((5 < Robustness) && (Robustness <= 10))

            printf("The Robustness is still need to be improved!");

        if(Robustness >10)

            printf("It's a Robust enough password");

    }while(strcmp(c, "exit")); //If the user type in "exit", then

                               //terminate the tester

                               //end of while

}

    后记:这篇文章是老早之前写的,本来想用来当毕业论文的,但是感觉太简单拿不出手,就自己收藏
了。:P
    在此,再附上自己对这个算法的时间复杂性分析(大牛请略过:P)。设密码字符串的长度为N,则取第i个字符和第i+1个字符,计算字符ascii码差值并转换为绝对值,将差值累加三个操作各需要O(1)的时间,而这样的操作需要进行N次(因为最后还要计算字符串最后一个字符跟第一个字符的差值),所以总共耗费的时间为N*4*O(1) = O(N),可见为线性时间。当然,当时程序中没有考虑数组c越界的问题,确实是一个bug。不过,明天我会将图形界面的程序写出来,算是这个程序的升级版吧。
 

2008-1-14 0:05
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息