加密算法MD5
在我国所有的网络公司都是不能直接获取到用户的密码的,所以加密算法就十分的必要。
这章在之前的用户管理模块的基础上加上了加密模块。
- 这些是我这两天对用户管理模块的学习和补充过程,有兴趣的同学可以看看,相互交流一下。
1.用c语言完成的用户管理系统
2.基于多文件编程,完善用户管理模块
3.基于文本编辑完成用户管理模块的数据持久化
移植算法md5
这里是我用的md5的函数资料,以此为基础我将他移植到我的程序中,完成了对该模块的补充。
他的源码太长了,这里就不放了。函数为md5.c头文件为md5.h。
原文中的调用
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5, argv[1], strlen(argv[1]));
unsigned char decrypt[16];
MD5Final(&md5, decrypt);
char passwd[33] = {};
for(int i=0; i<16; i++)
{
sprintf(passwd+i*2,"%02x", decrypt[i]);
}
printf("%s\n", passwd);
return 0;
将函数封装到tools文件中
注意在修改函数时一定要先修改头文件
//加密
void cry(char* pd,char*jo)
{
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,(unsigned char*)pd,strlen(pd));
unsigned char decrypt[16];
MD5Final(&md5, decrypt);
//char passwd[33] = {};
for(int i=0; i<16; i++)
{
sprintf(jo+i*2,"%02x", decrypt[i]);
}
return;
}
移植
由于要添加加密功能,所以我们程序里用到密码的地方都需要修改。
找到用户模块,一共有三个地方用到了密码
1.注册函数void enroll(void);
while(1)
{
char password_0[7];
char password_1[7];
printf("请设置用户密码:");
get_passwd(password_0,sizeof(password_0));
printf("请再次输入密码:");
get_passwd(password_1,sizeof(password_1));
if(0 == strcmp(password_1,password_0))
{
cry(password_1,id[cnt].password);
printf("%s\n",id[cnt].password);
break;
}
else
printf("\n输入错误,请重新输入\n\n");
}
2.登录函数int goup_password(void);
printf("请输入密码:");
do
{
get_passwd(password_,sizeof(password_));
cry(password_,password_0);
if(0==strcmp(password_0,id[cnt_yz].password))
{
return nosuo;
id[cnt_yz].lock=0;
}
else
{
id[cnt_yz].lock++;
if('4'==id[cnt_yz].lock)
return suo;
printf("你输入的密码错误,您还有%d次机会,请重新输入",'4'-id[cnt_yz].lock);
}
}while(1);
3.修改用户信息void revise(void);
今天修改的时候发现这个模块设置的界面和功能很不合理,所以稍作了修改。
//修改信息
void revise(void)
{
char password_0[7];
char password_1[32];
while(1)
{
// 显示信息列表
printf("\n\n\n修改姓名输入指令”1“\n修改密码输入指令”2“\n修改联系方式输入指令”3“\n");
// 获取指令并调用功能函数
switch(get_cmd('1','4'))
{
case '1': {
printf("请输入新的姓名:");
get_str(id[cnt_yz].name,sizeof(id[cnt_yz].name));
break;
}
case '2': {
printf("请输入旧的密码:");
do
{
get_passwd(password_0,sizeof(password_0));
cry(password_0,password_1);
if(0 == strcmp(password_1,id[cnt_yz].password))
break;
printf("\n密码错误,请重新输入:");
}while(1);
while(1)
{
char password_0[7];
char password_1[7];
printf("请输入新密码:");
get_passwd(password_0,sizeof(password_0));
printf("请再次输入密码:");
get_passwd(password_1,sizeof(password_1));
if(0 == strcmp(password_1,password_0))
{
cry(password_1,id[cnt].password);
printf("%s\n",id[cnt].password);
break;
}
else
printf("\n输入错误,请重新输入\n\n");
}
get_passwd(id[cnt_yz].password,sizeof(id[cnt_yz].password));
break;
}
case '3':{
printf("请输入新的联系方式:");
get_str(id[cnt_yz].phone,sizeof(id[cnt_yz].phone));
break;
}
case '4':return ;
}
}
}
错误
由于密码做了加密处理,所以结构体里的成员id.password[33]
数组长度需要改变为33.
这里要注意,最开始更改的时候没有预留'\0'
的位置,导致读取的时候有数组越界。
- 数组越界 :
代码在编译时编译器不会检查数组的下标是否合法,因为数组的下标可以是变量,而在编译时变量值是不确定的,所以无法检查,从语法角度来说,数组可以越界访问,但这种行为是一种非法使用内存,造成的后果有三种情况:
1、一切正常。
2、段错误。
3、脏数据。
所以在使用字符串数组的时候一定要预留’\0’的位置。