OpenSSL: 消息摘要算法


簡單接口:

簡單接口使用一個函數調用就可以完成消息摘要計算,這些接口包括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; }

  檢驗:

f:\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://weiqi1981.blog.163.com/blog/static/18233663620122144583699/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM