BIO_set_md

news/2024/11/10 0:27:34

opensslengine机制实现chiper,digest的替换遇到问题了,到底EVP是怎么样调用init,updata,final以及init,updata,final应该如何实现呢?

---------------------------------

消息摘要算法

简单接口

简单接口使用一个函数调用就可以完成消息摘要计算,这些接口包括MD2,MD4,MD5,MDC2,RIPEMD,SHA1,函数声明都一样。

MD5为例,函数声明为:

unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md);

其中 d 指向要计算消息摘要的数据,n 为数据长度,md 指向保存消息摘要的缓冲区。如果 md 不为 NULL,那么它的长度必须能够容纳计算出来的消息摘要。对MD5,这个长度至少是 MD5_DIGEST_LENGTH。如果 md 为 NULL,那么计算出来的消息摘要保存在一个静态数组里,函数返回指向这个数组的指针。

    下面是一个使用MD()计算消息摘要的小程序:

//ex1.cpp

#include <stdio.h>

#include <string.h>

#include <openssl/md5.h>

static char *hexstr(unsigned char *buf,int len)

{

     const char *set = "0123456789abcdef";

     static char str[65],*tmp;

     unsigned char *end;

     if (len > 32)

         len = 32;

     end = buf + len;

     tmp = &str[0];

     while (buf < end)

     {

         *tmp++ = set[ (*buf) >> 4 ];

         *tmp++ = set[ (*buf) & 0xF ];

         buf ++;

     }

     *tmp = '';

     return str;

}

int main(int argc, char* argv[])

{

     char *buf = "Hello,OpenSSL\n";

     unsigned char *md;

     md = MD5((const unsigned char*)buf,strlen(buf),NULL);

     printf("%s\n",hexstr(md,MD5_DIGEST_LENGTH));

     return 0;

}

 

这个程序计算出字符串”Hello,OpenSSL\n”的消息摘要为97aa490ee85f397134404f7bb524b587。可以用Unix下的md5sum程序检验是否正确:

[root@cat /root]# echo "Hello,OpenSSL" | md5sum

97aa490ee85f397134404f7bb524b587  -

可以看到结果一样。

其它算法的计算类似,只用替换源代码中的md5为相应的算法名即可。

 

标准接口

简单接口容易使用,但是它要求被摘要数据在时间和空间上都是连续的。要

计算不连续数据的摘要,就必须使用标准接口。事实上,简单接口也是通过调用标准接口工作的。

    以MD5为例,标准接口包括如下函数:

    void MD5_Init(MD5_CTX *c);

    void MD5_Update(MD5_CTX *c,const void *data,unsigned long len);

    void MD5_Final(unsigned char *md, MD5_CTX *c);

MD5_Init初始化MD5_CTX结构,MD5_Update计算摘要,MD5_Final输出摘要值。

    下面是使用标准接口的 ex1.cpp 程序(只有main函数不同):

//ex2.cpp

//包含的头文件,hexstr函数都和 ex1.cpp一样

int main(int argc, char* argv[])

{

     char *buf = "Hello";

     char *buf2 = ",";

     char *buf3 = "OpenSSL\n";

     unsigned char md[MD5_DIGEST_LENGTH];

     MD5_CTX ctx;

     MD5_Init(&ctx);

     MD5_Update(&ctx,buf,strlen(buf));

     MD5_Update(&ctx,buf2,strlen(buf2));

     MD5_Update(&ctx,buf3,strlen(buf3));

     MD5_Final(md,&ctx);

    

     printf("%s\n",hexstr(md,MD5_DIGEST_LENGTH));

     return 0;

}

检验:

    E:\ssl\md5\ex2\Debug>ex2

97aa490ee85f397134404f7bb524b587

可以看出,和 ex1 和 md5sum 的结果一致。   

EVP 接口

#include <stdio.h>

#include <string.h>

#include <openssl/evp.h>

static char *hexstr(unsigned char *buf,int len)

{

     const char *set = "0123456789abcdef";

     static char str[65],*tmp;

     unsigned char *end;

     if (len > 32)

         len = 32;

     end = buf + len;

     tmp = &str[0];

     while (buf < end)

     {

         *tmp++ = set[ (*buf) >> 4 ];

         *tmp++ = set[ (*buf) & 0xF ];

         buf ++;

     }

     *tmp = '';

     return str;

}

int main(int argc, char* argv[])

{

     char *buf = "Hello";

     char *buf2 = ",";

     char *buf3 = "OpenSSL\n";

     unsigned int mdlen;

     unsigned char md[EVP_MAX_MD_SIZE];

     EVP_MD_CTX ctx;

     const EVP_MD *type = EVP_md5();

     OpenSSL_add_all_digests();

     if (argc > 1)

     {

         type = EVP_get_digestbyname(argv[1]);

         if (type == NULL)

         {

              fprintf(stderr,"Use default : MD5\n");

              type = EVP_md5();

         }

     }

     EVP_DigestInit(&ctx,type);

     EVP_DigestUpdate(&ctx,buf,strlen(buf));

     EVP_DigestUpdate(&ctx,buf2,strlen(buf2));

     EVP_DigestUpdate(&ctx,buf3,strlen(buf3));

     EVP_DigestFinal(&ctx,md,&mdlen);    

     printf("%s\n",hexstr(md,mdlen));

     return 0;

}

BIO 接口

BIO_f_md()返回消息摘要的BIO方法。任何经过一个消息摘要BIO的数据都

被自动摘要。BIO_set_md设置一个消息摘要BIO所使用的摘要算法。

    下面是使用BIO的MD5例子:

#include <stdio.h>

#include <string.h>

#include <openssl/evp.h>

#include <openssl/bio.h>

static char *hexstr(unsigned char *buf,int len)

{

     const char *set = "0123456789abcdef";

     static char str[65],*tmp;

     unsigned char *end;

     if (len > 32)

         len = 32;

     end = buf + len;

     tmp = &str[0];

     while (buf < end)

     {

         *tmp++ = set[ (*buf) >> 4 ];

         *tmp++ = set[ (*buf) & 0xF ];

         buf ++;

     }

     *tmp = '';

     return str;

}

int main(int argc, char* argv[])

{

     int len;

     const char *str = "Hello,OpenSSL\n";

     BIO *bio_null,*bio_md;

     unsigned char md[EVP_MAX_MD_SIZE];

     bio_null = BIO_new(BIO_s_null());

     bio_md = BIO_new(BIO_f_md());

     BIO_set_md(bio_md,EVP_md5());

     bio_md = BIO_push(bio_md,bio_null);

     BIO_write(bio_md,str,strlen(str));

     BIO_flush(bio_md);

     len = BIO_gets(bio_md,(char*)md,EVP_MAX_MD_SIZE);

     printf("%s\n",hexstr(md,len));

     BIO_free_all(bio_md);

     return 0;

}    

 

检验结果为:97aa490ee85f397134404f7bb524b587,与md5sum的结果相同,注意消息摘要BIO比较特殊:数据经过这种BIO不被修改,只是摘要值保留在BIO中,需要用BIO_gets而不是BIO_read读取

 

 


http://www.niftyadmin.cn/n/4615969.html

相关文章

Struts2 实例

https://my.oschina.net/jerrypan/blog/621192

静态SDRAM和动态SDRAM的区别

SDRAM有一个同步接口&#xff0c;在响应控制输入前会等待一个时钟信号&#xff0c;这样就能和计算机的系统总线同步。时钟被用来驱动一个有限状态机&#xff0c;对进入的指令进行管线(Pipeline)操作。这使得SDRAM与没有同步接口的异步DRAM相比&#xff0c;可以有一个更复杂的操…

MyGui 3.01编译

1、需要安装的组件 FreeType 下载地址&#xff1a; 二进制包&#xff1a;http://sourceforge.net/projects/gnuwin32/files/freetype/2.3.5-1/freetype-2.3.5-1-setup.exe/download SDK及源码&#xff1a;http://sourceforge.net/projects/gnuwin32/files/freetype/2.3.5-1/fre…

一些时下很潮词的翻译

伪球迷 biased fans紧身服 straitjacket团购 group buying奉子成婚 shortgun marriage婚前性行为 premartial sex开博 to open a blog家庭暴力 family volience问题家具 problem furniture炫富 flaunt wealth决堤 breaching of the dike上市 list share soccer gambling桑拿…

HTML标签之label标签的坑

之前写过一个项目&#xff0c;要用到label标签&#xff0c;页面中有&#xff0c;弹窗也有。 遇到的问题&#xff1a;点击弹窗的label选中的确是页面的框。 原因&#xff1a;页面中的数据和弹窗的数据一致&#xff0c;导致label标签中的for的值重复了&#xff0c;所以才会出现此…

汽车导航系统应用富士通FRAM铁电存储器MB85R2001

MB85R2001是一种富士通FRAM芯片&#xff0c;由262,144字8位非易失性存储单元组成&#xff0c;这些单元使用铁电工艺和硅栅CMOS工艺技术创建。能够保留数据&#xff0c;而无需使用SRAM所需的备用电池。MB85R2001中使用的存储单元可用于1010次读/写操作&#xff0c;与Flash存储器…

指针字符串

指针字符串 用指针遍历字符串中字符, 上面的例子是用指针指向字符串中的首个字符,下面的例子是用指针直接指向字符串; (上面的例子的做法是先定义一个字符串数组,用于存放字符串,然后将数组首地址传给指针p,让指针p指向字符串数组的首个字符地址); C中string.h头文件中包含的st…

DVB-T2 学习笔记(02) - 输入处理

5. 输入处理 5.1 Mode adaptation T2系统的输入应该包括一个或多个逻辑数据流。每个数据流被一个PLP承载。而mode adaptation模块&#xff0c;把每个PLP的输入数据流分割成许多数据区&#xff0c;通过stream adaptation后&#xff0c;就形成了基带帧(BBFRAME)。mode adaptation…