用Openssl 做hash(C++)
来源:互联网 发布:数组是js数据类型吗? 编辑:程序博客网 时间:2024/06/06 05:26
转自:http://linux.die.net/man/3/evp_sha512
代码如下:
// mdtest.cpp#include <stdio.h>#include <string.h>#include <openssl/evp.h>int main(int argc, char* argv[]){EVP_MD_CTX mdctx;const EVP_MD *md;char mess1[] = "Test Message\n";char mess2[] = "Hello World\n";unsigned char md_value[EVP_MAX_MD_SIZE];unsigned int md_len;int i;OpenSSL_add_all_digests();if(!argv[1]) { printf("Usage: mdtest digestname\n"); exit(1);}md = EVP_get_digestbyname(argv[1]);if(!md) { printf("Unknown message digest %s\n", argv[1]); exit(1);}EVP_MD_CTX_init(&mdctx);EVP_DigestInit_ex(&mdctx, md, NULL);EVP_DigestUpdate(&mdctx, mess1, strlen(mess1));EVP_DigestUpdate(&mdctx, mess2, strlen(mess2));EVP_DigestFinal_ex(&mdctx, md_value, &md_len);EVP_MD_CTX_cleanup(&mdctx);printf("Digest is: ");for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);printf("\n");return 0;}
假设我们知道openssl 的头文件位于 /yasi/code/openssl-1.0.1c/include,而openssl 库文件位于 /usr/lib64,用下面的命令编译:
g++ -o mdtest mdtest.cpp -I/yasi/code/openssl-1.0.1c/include -lssl -lcrypto -L/usr/lib64
运行及结果:
./mdtest sha1Digest is: 0541d4e2b052e6ed4bb7e294a1884c2cfbbf30d8./mdtest sha224Digest is: 1398d1428f5449ddad27d18c78d06ca1831937d2e342dafc76b693be./mdtest sha256Digest is: 318b20b83a6730b928c46163a2a1cefee4466132731c95c39613acb547ccb715./mdtest sha384Digest is: 22511d0e8dfafe6ea698635d2e549056f8d48eba210a2b7040a3d89830660b1c1f5d38e218e86d036e489b1121b1bfc1./mdtest sha512Digest is: bcc37e0208be19c45906c47bbf09dc07c7b9e8614759dd3f85ebe39c1b1e1fcd6d804e36ee0be3cf3d3b57d9f28845de522b641937bbadaf98becacdb0572498
注意:
代码中的 EVP_MAX_MD_SIZE 的值应该是64,因为SHA512编码后长度是64字节。但事实上,有时会发现这个宏的值在Openssl中定义为36,这时需要自己重新定义它为64:
#define EVP_MAX_MD_SIZE 64 /* SHA512 */
EVP_DigestFinal_ex(&mdctx, md_value, &md_len) 的 md_len 参数是output参数,“EVP_DigestFinal_ex 往 md_value 中写入了多少字节的内容”,这个信息(写入信息长度)将被写入 md_len。
独立的代码:
下面的代码可以直接拿来用
algo_hash.h
#ifndef _ALGO_HASH_H_#define _ALGO_HASH_H_void HashInit();int HashEncode(const char * algo, const char * input, unsigned int input_length, char * &output, unsigned int &output_length);#endif
algo_hash.cpp
#include "algo_hash.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include <openssl/evp.h>void HashInit() { OpenSSL_add_all_digests();}int HashEncode(const char * algo, const char * input, unsigned int input_length, char * &output, unsigned int &output_length) { EVP_MD_CTX ctx; const EVP_MD * md = EVP_get_digestbyname(algo); if(!md) { printf("Unknown message digest algorithm: %s\n", algo); return -1; } output = (char *)malloc(EVP_MAX_MD_SIZE); memset(output, 0, EVP_MAX_MD_SIZE); EVP_MD_CTX_init(&ctx); EVP_DigestInit_ex(&ctx, md, NULL); EVP_DigestUpdate(&ctx, input, input_length); EVP_DigestFinal_ex(&ctx, (unsigned char *)output, &output_length); EVP_MD_CTX_cleanup(&ctx); return 0;}
测试代码 main.cpp
#include "algo_hash.h"#include "stdio.h"#include <iostream>#include <string>using namespace std;void hex_output(const char * buff, unsigned int length) { for(int i = 0; i < length; ++i) { printf("%-3x", (unsigned char)(*(buff + i))); } cout << endl;}int main(int argc, char* argv[]) { if(argc < 2) { cout << "Algorithm is required!" << endl; return -1; } HashInit(); string input = "DFADGJAOUEORQ798686VX8X7B8FG97"; char * output = NULL; unsigned int output_length = 0; int result = HashEncode(argv[1], input.c_str(), input.length(), output, output_length); cout << "Result: " << result << endl; cout << "Input length: " << input.length() << endl; cout << "Input: " << input << "~" << endl; cout << "Output length: " << output_length << endl; cout << "Output: " << endl; hex_output(output, output_length); return 0;}Makefile
INC_OPT = -I/usr/include/openssl -I. -gLNK_OPT = -L/usr/lib64 -lssl -gall: g++ $(INC_OPT) -c algo_hash.cpp g++ $(INC_OPT) -c main.cpp g++ $(LNK_OPT) -o test algo_hash.o main.oclean: rm -f *.o test
各种算法Hash后的子串的长度
【补充】
如果只想做SHA1,可以用 https://www.openssl.org/docs/crypto/sha.html 介绍的下面函数。
unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md);
类似的SHA256等函数,在openssl的源码中都有。
- 用Openssl 做hash(C++)
- 用OpenSSL 做HMAC(C++)
- 用OpenSSL 做HMAC(C++)
- 用OpenSSL 做Base64 编解码(C++)
- 用OpenSSL做自签名的证书
- 用c做存储之一:hash表结构、应用场景及实现
- openssl passwd 计算密码hash
- 再写 Hash (C++)
- c-Hash
- c hash
- 用OpenSSL结合ACE 做安全网络通信
- 用openssl制作小CA做https通信
- Linux下用openssl库做md5加密
- 用OpenSSL做自签名的证书(by quqi99)
- 用openssl自做CA自签发SSL证书
- 【POJ1743】Musical Themes 乐曲主题 后缀数组、 (也可以用hash+二分做的~)
- winAPI做hash加密
- winAPI做hash加密
- java.lang.NoClassDefFoundError: com.weibo.net.Weibo错误
- shell脚本中的$*,$@和$#
- Camshift算法原理及其Opencv实现
- oracle 11G 11.2.0.1.0使用exp无法导出空表的解决办法
- 在csdn上安个家
- 用Openssl 做hash(C++)
- 项目管理中的冲突管理
- mysql命令行修改字符编码
- 关于装双Win7系统方法及问题:错误0x80070571:磁盘结构损坏且无法读取
- mssql order by语句怎么把null,空值的字符或日期排在最后
- 10个iPhone开发网站、论坛、博客
- 建立空间参考 ISpatialReference
- Expression Blend4下载步骤
- 如果不坚强,软弱给谁看