使用C++模拟动态密码验证

前言

主要是最近特别想写一个保密的网站系统。然后自己大概考虑了一个实现方法,然后经过测试发现有效。后来在网上找有没有更好的解决方案,然后惊奇地发现这方面居然没有人来提供教程。

然后本菜鸡就把自己的方法放送出来,方便大家在进行各种开发的时候使用动态密码算法。

实现原理

其实整个原理是比较简单的。

比如说现在有两个设备,服务端和客户端。

两部设备同时拥有时钟和一套相同的算法。当用户需要一个新的动态密码时,两个设备会通过各自的时钟,使用相同的算法来计算出两个密码。此时,用户手中的密码应该是客户端的密码。在两个设备的时钟相同时,对应生成的密码也相同。用户输入客户端提供的密码到服务器进行验证,若密码相同,则验证通过。

所以现在需要模拟生成密码的算法。我在这里提供了一个很菜的算法,大家可以拿来参考一下。

编程实现

核心函数

这里面最核心的函数是ctime库中的两个函数:

time_t tt=time(NULL);
tm *t=localtime(&tt);

time函数用于获取系统时间,而localtime函数则将time_t数据转换成可读的数据。

读取时间的方法如下:

t->tm_year+1900 //年
t->tm_mon+1     //月
t->tm_mday      //日
t->tm_hour      //小时
t->tm_min       //分钟
t->tm_sec       //秒

使用这些数据来计算一个密码出来。

每隔一段时间修改一次

这个可以通过对秒整除和取余来实现。

比如说,我想让这个代码20秒换一次,那么我就可以:

sec=sec/code_time+1;

这样一来,sec变量中存储的值只有20秒才会变化一次。

主程序

安全验证

这个并不是必要的,只是为了防止任何人都能轻易使用这套程序。

//以下为全局内容

string password="123456";
string input()
{
    char geted=getch();
    string outed;
    while(geted!=13)
    {
        cout<<"*";
        outed+=geted;
        geted=getch();
    }
    cout<<endl;
    return outed;
}

//以下为主程序中的内容

    cout<<"Current security code : UNKNOWN"<<endl;
    cout<<"Code change : UNKNOWN"<<endl;

    string check;
    int timesss=1;
    for(timesss=1;timesss<=3;timesss++)
    {
        cout<<"Security pass required : ";
        check=input();
        if(check==password) break;
        else cout<<"[ERROR]Invalid pass! Chances remained : "<<3-timesss<<endl;
    }
    if(timesss>3)
    {
        cout<<"[DENIED]SECURITY PASS FAILED!"<<endl;
        getch();
        return 0;
    }

这个小型密码安全验证提供三次输入密码机会,并且自动将输入的密码变成“*”,以增加安全性。

生成器

使用这个函数来根据当前时间计算一个新的动态密码。

int code_time=20;   //安全代码刷新时间 
int code_len=6;     //安全代码长度 

string trim(string a,int len)
{
    string b;
    len=min(len,(int)a.length());
    for(int i=0;i<len;i++)
    {
        b+=a[i];
    }
    return b;
}

string generate(tm *t,int len)
{
    int year=t->tm_year+1900;
    int mon=t->tm_mon+1;
    int day=t->tm_mday;
    int hour=t->tm_hour;
    int min=t->tm_min;
    int sec=t->tm_sec;

    unsigned int result=(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*min*min*min*year*year*mon*mon*day*day+day*day*(sec/code_time+1)*(sec/code_time+1)*(hour+1)*(hour+1)*(min+1)-min;
    int a=result%2147480000+100000;

    char str[55];
    itoa(a,str,10);//将数字转换成字符数组存储到str中
    return trim(str,len);
}

trim(string)函数用于剪切字符串,提取字符串的前6位。

generate(tm,int)函数提供了一个非常暴力的算法,当然你也可以更换其中的算法,使得它随机性更高。

主循环

如果你想在程序启动的时候一直动态获取密码,并且显示还剩多长时间改变,那么你可以参照以下的代码:

    while(true)
    {
        tt=time(NULL);
        t=localtime(&tt);
        int time_remain=code_time-(t->tm_sec)%code_time-1;
        if(time_remain==code_time-1||!out)
        {
            out=true;
            system("cls");
            cout<<"Current security code : "<<generate(t,6)<<endl;
            cout<<"Code change : "<<time_remain;
            Sleep(100);
        }
        else
        {
            cout<<"                                \rCode change : "<<time_remain;
        }
        Sleep(100);
    }

像这样。每隔100毫秒读取一次系统时间,如果系统察觉到了密码应该变化,那么就重新计算一组密码。

完整源代码

在这里放出程序的完整源代码,方便进行学习、交流。

如果有更好的建议或者我讲的东西有任何问题,欢迎私信我,谢谢!

#include<iostream>
#include<ctime>
#include<string>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<conio.h>
using namespace std;

int code_time=20;   //安全代码刷新时间 
int code_len=6;     //安全代码长度 
string password="123456";//保护密码 

string input()
{
    char geted=getch();
    string outed;
    while(geted!=13)
    {
        cout<<"*";
        outed+=geted;
        geted=getch();
    }
    cout<<endl;
    return outed;
}

string trim(string a,int len)
{
    string b;
    len=min(len,(int)a.length());
    for(int i=0;i<len;i++)
    {
        b+=a[i];
    }
    return b;
}

string generate(tm *t,int len)
{
    int year=t->tm_year+1900;
    int mon=t->tm_mon+1;
    int day=t->tm_mday;
    int hour=t->tm_hour;
    int min=t->tm_min;
    int sec=t->tm_sec;

    unsigned int result=(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*min*min*min*year*year*mon*mon*day*day+day*day*(sec/code_time+1)*(sec/code_time+1)*(hour+1)*(hour+1)*(min+1)-min;
    int a=result%2147480000+100000;

    char str[55];
    itoa(a,str,10);
    return trim(str,len);
}

int main()
{
    time_t tt=time(NULL);
    tm *t=localtime(&tt);
    bool out=false;

    cout<<"Current security code : UNKNOWN"<<endl;
    cout<<"Code change : UNKNOWN"<<endl;

    string check;
    int timesss=1;
    for(timesss=1;timesss<=3;timesss++)
    {
        cout<<"Security pass required : ";
        check=input();
        if(check==password) break;
        else cout<<"[ERROR]Invalid pass! Chances remained : "<<3-timesss<<endl;
    }
    if(timesss>3)
    {
        cout<<"[DENIED]SECURITY PASS FAILED!"<<endl;
        getch();
        return 0;
    }

    while(true)
    {
        tt=time(NULL);
        t=localtime(&tt);
        int time_remain=code_time-(t->tm_sec)%code_time-1;
        if(time_remain==code_time-1||!out)
        {
            out=true;
            system("cls");
            cout<<"Current security code : "<<generate(t,6)<<endl;
            cout<<"Code change : "<<time_remain;
            Sleep(100);
        }
        else
        {
            cout<<"                                \rCode change : "<<time_remain;
        }
        Sleep(100);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/rentenglong2012/article/details/78158791