赞
踩
MD5信息摘要算法
(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value)。摘要算法,是一个不可逆过程,就是与数据大小无关,经过算法运算后都是生成固定长度的一组数据,结果为16进制进行显示的128bit的二进制串。通常表示为32个十六进制数连成的字符串。
一、linux md5的应用
1、使用mdsum命令
echo -n “abcdefg” | md5sum |tr a-z A-Z
输出结果:7AC66C0F148DE9519B8BD264312C4D64
2、使用openssl md5
echo -n “abcdefg” | openssl md5 |tr a-z A-Z
输出同样结果:7AC66C0F148DE9519B8BD264312C4D64
注释:
-n 参数,强制去掉echo时回车,不然输出结果是错误的。
|tr a-z A-Z 参数,将输出结果转化为大写字母。
3、使用标准C测试
调用库 #include<openssl/md5.h>
主要用下面几个函数
数据大的话用下面三个函数。
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
很简单的一组字符串可以直接用下面这个函数。
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
写完代码,编译时需加参数-lcrypto调用openssl动态库,不然会出错
gcc -lcrypto test.c -o test
md5.h库内容显示如下:
/* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #ifndef HEADER_MD5_H # define HEADER_MD5_H # include <openssl/opensslconf.h> # ifndef OPENSSL_NO_MD5 # include <openssl/e_os2.h> # include <stddef.h> # ifdef __cplusplus extern "C" { # endif /* * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * ! MD5_LONG has to be at least 32 bits wide. ! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ # define MD5_LONG unsigned int # define MD5_CBLOCK 64 # define MD5_LBLOCK (MD5_CBLOCK/4) # define MD5_DIGEST_LENGTH 16 typedef struct MD5state_st { MD5_LONG A, B, C, D; MD5_LONG Nl, Nh; MD5_LONG data[MD5_LBLOCK]; unsigned int num; } MD5_CTX; int MD5_Init(MD5_CTX *c); int MD5_Update(MD5_CTX *c, const void *data, size_t len); int MD5_Final(unsigned char *md, MD5_CTX *c); unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); void MD5_Transform(MD5_CTX *c, const unsigned char *b); # ifdef __cplusplus } # endif # endif #endif
例子:vi md5.c
#include<stdio.h> #include<string.h> #include<openssl/md5.h> void test1() { unsigned char *str= "20:35:6E:18:2A:86"; unsigned char md[16]; int i; char temp[3]; char code[33]; MD5(str,strlen(str),md); for (i = 0; i < 16; i++){ sprintf(temp,"%2.2X",md[i]); strcat(code,temp); } printf("test1 str to code:%s\n",code); } void test2() { MD5_CTX ctx; unsigned char *str= "20:35:6E:18:2A:86"; unsigned char md[16]; int i; char temp[3]; char code[33]; MD5_Init(&ctx); MD5_Update(&ctx,str,strlen(str)); MD5_Final(md,&ctx); for( i=0; i<16; i++ ){ sprintf(temp,"%02X",md[i]); strcat(code,temp); } printf("test2 str to code:%s\n",code); } int main( int argc, char **argv ) { test1(); test2(); return 0; }
输出结果:
test1 str to code:2C0EC30AA819B957D997343135D5268B
test2 str to code:2C0EC30AA819B957D997343135D5268B
二、实用栗子
自定算法简易描述如下:
1、列出设备网络MAC字符串
2、以某种方式生成一个随机数
3、将生成的随机数按既定方式混入MAC字符串中
4、然后将字符串的头部增加固定字符,尾部增加固定字符,连接生成一个新字符串。
5、将新字符串使用md5算法计算出一组32位hex字符串
6、把32个字符串分解为32个整型数据,依次乘以一个定值,循环累加。
7、将最终的累加值以字符串形式输出。
三、具体代码
下面代码在openEuler环境下用gcc和termux环境下用clang均通过测试,仅供学习参考研究,不作他用。
vi test.c
gcc -lcrypto test.c -o test
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<openssl/md5.h> //#pragma clang diagnostic ignored "-Wpointer-sign" //gcc md5.c -o ~/md5 -lcrypto char *mac_str(char *mac,char *rand) { int i,mac_len,rand_len,offset; char mac_b[50]; char temp[4]; char mac1[19]; char rand1[7]; strcpy(mac1,mac); strcpy(rand1,rand); rand_len= strlen(rand); mac_len = strlen(mac); mac[mac_len-1] = rand[rand_len-1]; offset = 0; for (i=0;i<mac_len;i++) { if (mac[i] == ':') { mac[i] = rand[offset]; offset += 1; } } if (rand[0] == 'C') { for (i=0;i<mac_len;i++) { sprintf(temp,"%d",mac[i]); strcat(mac_b,temp); } } return mac; } int adb_key(char *rand_s,char *mac_s) { char r[7],m[19]; char buf[50]; int i,result; char p[10]; char str[50]; unsigned char buf_u[50]; unsigned char md_u[16]; strcpy(r,rand_s); strcpy(m,mac_s); sprintf(buf,"linux%s@%sHW_openEuler",r,m); for (i=0;i<strlen(buf);i++) { buf_u[i]=(int)buf[i]; } MD5(buf_u,strlen(buf),md_u); str[0]='\0'; for (i=0;i<sizeof(md_u);i++) { p[0]='\0'; sprintf(p,"%2.2X",md_u[i]); strcat(str,p); } result=0; for (i=0;i<strlen(str);i++) { result=(int)(str[i])+31*result; } if (result<0) result=-result; return result; } int main(int argc, char* argv[]) { char input_mac[19]; char input_rand[7]; char check[19]; int key; printf("input mac press enter,for example:04:15:A3:3E:58:8A\n"); scanf("%s",input_mac); printf("input rand press enter,for example:C78369\n"); scanf("%s",input_rand); strcpy(check,mac_str(input_mac,input_rand)); key=adb_key(input_rand,check); printf("Success! key is:\n%d\n",key); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。