红联Linux门户
Linux帮助

在Ubuntu 14.04 64bit上进行md5加密编程

发布时间:2015-09-09 16:18:38来源:linux网站作者:雪峰流云

计算指定字符串的md5值是一项很常见的操作,包括使用命令行md5sum,或者在C/C++编程中调用openssl提供的接口函数来进行。下面我们分别阐述如下:


一、在命令行中使用md5校验

计算某个文件的md5校验值,通常就是在命令行输入md5sum就可以了

但是如果要方便地计算一个给出字符串的md5值,则md5sum就不合适了,因为md5sum只针对文件操作。为此我想到下面的变通方法:

在/usr/bin下面编写一个bash脚本

sudo vim md5

#!/bin/bash 
echo -n $1 | md5sum | awk '{print $1}' 

保存后,赋予可执行权限

sudo chmod +x md5

这样就可以方便地计算任意字符串的值了。参见如下截图

在Ubuntu 14.04 64bit上进行md5加密编程

在Ubuntu 14.04 64bit上进行md5加密编程


二、使用OpenSSL中md5接口编程(使用MD5加密)

我们以一个字符串为例,新建一个文件filename.txt,在文件内写入hello ,然后在Linux下可以使用命令md5sum filename.txt计算md5值 ==> b1946ac92492d2347c6235b4d2611184  。虽然写入的是hello这5个字符,但是我们使用命令xxd filename.txt后可以看出文件结尾处会有个0x0a这个回车符。所以在下面的代码中才会有\n。

在Ubuntu 14.04 64bit上进行md5加密编程

在Ubuntu 14.04 64bit上进行md5加密编程

下面是提供的md5函数的接口

//打开/usr/include/openssl/md5.h这个文件我们可以看到一些函数
// 初始化 MD5 Contex, 成功返回1,失败返回0
int MD5_Init(MD5_CTX *c);
// 循环调用此函数,可以将不同的数据加在一起计算MD5,成功返回1,失败返回0
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
// 输出MD5结果数据,成功返回1,失败返回0
int MD5_Final(unsigned char *md, MD5_CTX *c);
// MD5_Init,MD5_Update,MD5_Final三个函数的组合,直接计算出MD5的值
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
// 内部函数,不需要调用
void MD5_Transform(MD5_CTX *c, const unsigned char *b);


下面是分别针对字符串和本地文件的源码

str_md5_demo.c文件:

//gcc -g str_md5_demo.c -o str_md5_demo -lcrypto 
// 
#include <string.h> 
#include <stdio.h> 
#include <openssl/md5.h> 
 
int main(int argc, char* argv[]){ 
MD5_CTX ctx; 
unsigned char md[16] = {0}; 
int i = 0; 
 
//方法一: 
MD5_Init(&ctx); 
MD5_Update(&ctx, "hel", 3); 
MD5_Update(&ctx, "lo", 2); 
MD5_Final(md, &ctx); 
 
for (i = 0; i < 16; i++) 
printf("%02X", md[i]); 
printf("\n"); 
 
//方法二: 
const char data[] = "hello"; 
MD5(data, strlen(data), md); 
 
for (i = 0; i < 16; i++) 
printf("%02X", md[i]); 
printf("\n"); 
 
return 0; 

file_md5_demo.c:

//gcc -g file_md5_demo.c -o file_md5_demo -lcrypto 
// 
 
#include <string.h> 
#include <stdio.h> 
#include <openssl/md5.h> 
 
int main(int argc, char* argv[]){ 
MD5_CTX ctx; 
unsigned char md[16] = {0}; 
char buffer[1024] = {0}; 
char filename[64] = {0}; 
int len = 0, i; 
FILE* fp = NULL; 
 
printf("请输入文件名, 用于计算MD5值\n"); 
scanf("%s", filename); 
 
fp = fopen(filename, "rb"); 
if(NULL == fp){ 
printf("can't open file\n"); 
return 1; 

 
//方法一: 
MD5_Init(&ctx); 
while((len=fread(buffer, 1, sizeof(buffer), fp)) > 0){ 
MD5_Update(&ctx, buffer, len); 
memset(buffer, 0 ,sizeof(buffer)); 

MD5_Final(md, &ctx); 
 
for(i=0; i<16; i++) 
printf("%02X", md[i]); 
printf("\n"); 
 
//方法二: 
while((len=fread(buffer, 1, sizeof(buffer), fp)) > 0){ 
MD5(buffer, len, md); 
memset(buffer, 0 ,sizeof(buffer)); 

 
for(i=0; i<16; i++) 
printf("%02X", md[i]); 
printf("\n"); 
 
if(fp) fclose(fp); 
 
return 0; 


下面是运行效果截图, 同时给出了与md5或是md5check的对比图:

在Ubuntu 14.04 64bit上进行md5加密编程

在Ubuntu 14.04 64bit上进行md5加密编程


这里要说明如下几点:
1.md5接口的调用有两套,一套是 MD5_Init,MD5_Update,MD5_Final,另一套是MD5,用哪一套都可以的。两种实现方式,一样的结果。相比较,第二种方法更直观简单些。
2.进行计算的类型分为字符串和本地文件,
3.在Ubuntu 14.04 64bit上需要链接 -lcrypto,在ContOS上需要链接,不论是保存为c文件还是cpp文件
4.临时缓存一定要使用unsigned char,不能使用char,因为unsigned char 0~255 ,char -127~127。使用char会出问题。这个md5加密函数,返回16个十进制数,范围在0~255间,把它format为十六进制就是32位md5编码了。
5.snprintf时的格式,%02X和%2.2格式是一样的,强制输出两位,比如十进制的8,十六进制也是8,这个格式是控制输出两位,08。如果加密结果要小写字母显示,就是"%2.2x",大写就是"2.2X"。
6.运行得到结果后,我们可以使用md5sum命令进行验证,并对比。
7.注意这里用到openssl库,并且限定在Ubuntu上, 如果在CentOS平台上,可以运行 yum install openssl 和 yum install openssl-devel 进行安装。


在Ubuntu里校验下载软件的MD5值:http://www.linuxdiyf.com/linux/13190.html

Linux下计算文件的MD5值:http://www.linuxdiyf.com/linux/1407.html

Oracle中的MD5加密:http://www.linuxdiyf.com/linux/12466.html

浅谈MD5及简单使用:http://www.linuxdiyf.com/linux/1566.html