vc++网络安全编程范例(16)-open ssl 哈希编码解码数据
来源:互联网 发布:汪涵 知乎 编辑:程序博客网 时间:2024/04/30 15:11
OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。事实上,DES算法里面不仅仅是常用的DES算法,还支持三个密钥和两个密钥3DES算法。
OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法一般用户密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。
我们来用VC++实现使用哈希编码解码数据,请见代码实现与注释讲解
#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400#endif #include <stdio.h>#include <windows.h>#include <wincrypt.h>#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)//函数申明HCRYPTPROV GetCryptProv();void HandleError(char *s);void main(void){//变量申明及初始化BYTE* pbContent = (BYTE*) "A razzle-dazzle hashed message \n" "Hashing is better than trashing. \n"; // 与编码消息DWORD cbContent = strlen((char *)pbContent)+1; // 消息长度HCRYPTPROV hCryptProv; // CSP句柄DWORD HashAlgSize; //算法数据结构大小CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; //算法数据结构CMSG_HASHED_ENCODE_INFO HashedEncodeInfo; //哈希编码数据结构DWORD cbEncodedBlob; //编码消息长度BYTE *pbEncodedBlob; //编码 消息HCRYPTMSG hMsg; //消息句柄HCRYPTMSG hDupMsg;DWORD cbData = sizeof(DWORD);DWORD dwMsgType;DWORD cbDecoded;BYTE *pbDecoded;printf("开始处理. \n");printf("要被哈希处理及编码的消息是: \n");printf("%s\n",pbContent); // Display original message.printf("起初的消息长度是 %d\n",cbContent);//获取加密提供者句柄hCryptProv= GetCryptProv();//-------------------------------------------------------------------// 初始化算法数据结构.HashAlgSize = sizeof(HashAlgorithm);memset(&HashAlgorithm, 0, HashAlgSize); // 初始化为0HashAlgorithm.pszObjId = szOID_RSA_MD5; //指定算法为MD5哈希算法//-------------------------------------------------------------------// 初始化哈希编码数据结构memset(&HashedEncodeInfo, 0, sizeof(CMSG_HASHED_ENCODE_INFO));HashedEncodeInfo.cbSize = sizeof(CMSG_HASHED_ENCODE_INFO);HashedEncodeInfo.hCryptProv = hCryptProv;HashedEncodeInfo.HashAlgorithm = HashAlgorithm;HashedEncodeInfo.pvHashAuxInfo = NULL;//-------------------------------------------------------------------// 获取编码消息长度if(cbEncodedBlob = CryptMsgCalculateEncodedLength( MY_ENCODING_TYPE, // 编码类型 0, // 标志位 CMSG_HASHED, // 编码消息类型 &HashedEncodeInfo, // 执行消息类型指针 NULL, cbContent)) // 预编码消息长度{printf("需要被分配的长度是 %d 字节.\n",cbEncodedBlob);}else{HandleError("获取编码消息长度失败");}//-------------------------------------------------------------------// 为编码消息分配空间if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)){printf("已经分配了%d 字节的空间.\n",cbEncodedBlob);}else{HandleError("内存分配操作出错.");}//-------------------------------------------------------------------// 打开预编码消息if(hMsg = CryptMsgOpenToEncode(MY_ENCODING_TYPE, // 编码类型0, // 标志位CMSG_HASHED, // 编码消息类型&HashedEncodeInfo, // 执行消息类型指针NULL, NULL)) {printf("要编码的消息已经被打开. \n");}else{HandleError("打开预编码消息失败");}//-------------------------------------------------------------------// 编码消息,并加入消息句柄if(CryptMsgUpdate(hMsg, // 消息句柄pbContent, // 预编码消息cbContent, // 消息长度TRUE)) // 是否为最后一块数据{printf("编码后的数据已经被添加到编码消息中. \n");}else{HandleError("编码消息失败.");}//-------------------------------------------------------------------// 复制消息if(hDupMsg = CryptMsgDuplicate(hMsg)){ printf("此消息已经被复制.\n");}else{ HandleError("此消息复制失败.");}//-------------------------------------------------------------------// 从复制消息中获取参数,这里是获取编码消息内容if(CryptMsgGetParam( hDupMsg, // 消息句柄 CMSG_CONTENT_PARAM, // 参数类型 0, // 序号 pbEncodedBlob, // 数据指针 &cbEncodedBlob)) // 数据大小{ printf("消息编码成功. \n");}else {HandleError("获取编码消息参数失败");}//-------------------------------------------------------------------// 关闭消息CryptMsgClose(hMsg);CryptMsgClose(hDupMsg);// 下面的代码是解码哈希消息。一般来说,这段代码应在另外的应用程序中。// 编码后的数据及数据大小从文件或网络中获取//-------------------------------------------------------------------// 打开解码消息if(hMsg = CryptMsgOpenToDecode(MY_ENCODING_TYPE, // 编码类型0, // 标志位0, // 消息类型hCryptProv, // CSP句柄NULL, NULL)) { printf("要解码的消息已经被打开. \n");}else{ HandleError("打开预解码消息失败");}//-------------------------------------------------------------------// 解码消息,把解码后的消息加入到消息句柄中if(CryptMsgUpdate(hMsg, // 消息句柄pbEncodedBlob, // 编码消息指针cbEncodedBlob, // 编码消息长度TRUE)) // 是否为最后一块数据{ printf("解码后的数据被加入到解码消息中. \n");}else{HandleError("解码消息失败");}//-------------------------------------------------------------------// 获取数据类型if(CryptMsgGetParam( hMsg, // 消息句柄 CMSG_TYPE_PARAM, // 参数类型 0, // 序号 &dwMsgType, // 数据指针 &cbData)) // 数据大小{printf("消息类型已经被获取. \n");}else{HandleError("Decode CMSG_TYPE_PARAM failed");} //判断数据类型是否为哈希数据结构if(dwMsgType == CMSG_HASHED){ printf("此消息是哈希结构的消息. 继续. \n");}else{HandleError("消息类型错误.");}//-------------------------------------------------------------------// 获取解码后消息长度if(CryptMsgGetParam( hMsg, // 消息句柄 CMSG_CONTENT_PARAM, // 参数类型 0, // 序号 NULL, // 数据指针 &cbDecoded)) // 数据长度{printf("消息的长度 %d 已获取. \n", cbDecoded);}else{HandleError("Decode CMSG_CONTENT_PARAM failed");}//-------------------------------------------------------------------// 分配内存空间if(pbDecoded = (BYTE *) malloc(cbDecoded)){ printf("已经为解码后的消息分配了内存空间.\n");}else{HandleError("内存分配失败");}//-------------------------------------------------------------------// 获取解码后消息if(CryptMsgGetParam(hMsg, // 消息句柄CMSG_CONTENT_PARAM, // 参数类型0, // 序号pbDecoded, // 数据指针&cbDecoded)) // 数据长度 {printf("消息解码成功 \n");printf("解码后的消息是 \n%s\n", (LPSTR)pbDecoded);}else{HandleError("Decoding CMSG_CONTENT_PARAM #2 failed");}//-------------------------------------------------------------------// 验证哈希值if(CryptMsgControl( hMsg, // 消息句柄 0, // 标志位 CMSG_CTRL_VERIFY_HASH, // 控制类型 NULL)) {printf("哈希值验证成功. \n");printf("此数据未被篡改.\n");}else{ printf("哈希值验证失败.这个消息中某些内容发生改变 .\n");}printf("程序测试完成无错. \n");//-------------------------------------------------------------------// 释放内存if(pbEncodedBlob)free(pbEncodedBlob);if(pbDecoded)free(pbDecoded);CryptMsgClose(hMsg); // 释放CSP句柄if(hCryptProv) CryptReleaseContext(hCryptProv,0);} // End of main//获取加密提供者句柄HCRYPTPROV GetCryptProv(){HCRYPTPROV hCryptProv; // 加密服务提供者句柄//获取加密提供者句柄if(CryptAcquireContext(&hCryptProv, // 加密服务提供者句柄NULL, // 密钥容器名,这里使用登陆用户名NULL, // 加密服务提供者,这里取默认值 PROV_RSA_FULL, // 加密服务提供者类型,可以提供加密和签名等功能0)) // 标志{printf("加密服务提供者句柄获取成功!\n");}else{//删除掉密钥集if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET)){ HandleError("删除密钥集出错!");} //重新建立一个新的密钥集 if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)){ HandleError("重新建立一个新的密钥集出错!");} }return hCryptProv;}// HandleError:错误处理函数,打印错误信息,并退出程序void HandleError(char *s){ printf("程序执行发生错误!\n"); printf("%s\n",s); printf("错误代码为: %x\n.",GetLastError()); printf("程序终止执行!\n"); exit(1);}
- vc++网络安全编程范例(16)-open ssl 哈希编码解码数据
- vc++网络安全编程范例(18)-open ssl 实现数字证书编程
- vc++网络安全编程范例(17)-open ssl 实现文件加密与解密
- vc++网络安全编程范例(17)-open ssl 实现文件加密与解密
- VC++网络安全编程范例(10)-SSL网络通信
- VC++网络安全编程范例(10)-SSL网络通信
- VC++网络安全编程范例(11)-SSL高级加密网络通信
- VC++网络安全编程范例(11)-SSL高级加密网络通信
- VC++网络安全编程范例(7)-实现哈希摘要算法
- VC++网络安全编程范例(9)-基于OPENSSL实现对称算法与BASE64编码
- VC++网络安全编程范例(9)-基于OPENSSL实现对称算法与BASE64编码
- vc++网络安全编程范例(20)木马防范检测数据端口与进程
- vc++网络安全编程范例(21)用CryptoAPI进行数据加密
- VC++网络安全编程范例(12)-PKI编程
- vc++网络安全编程范例(13)-openssl engine编程
- vc++网络安全编程范例(14)-openssl bio编程
- VC++网络安全编程范例(12)-PKI编程
- vc++网络安全编程范例(13)-openssl engine编程
- 2011-12-13-16面试经历
- 在SQL server中设置时间格式
- 黎明的丰收
- Ubuntu面板右上角网络图标无法显示
- 以boost::function和boost:bind取代虚函数
- vc++网络安全编程范例(16)-open ssl 哈希编码解码数据
- 飞鸽传书 宣传单和电话说辞
- CMFCDesktopAlertWnd实现桌面弹出消息框
- axis2
- 入党转正申请书
- MOTO XT316 Android 3.2.4 ROOT [简单安全]
- 关于取模的运算
- 硬盘安装 Fedora 16 以及我的设置(纯属备忘)
- android Toast大全(五种情形)建立属于你自己的Toast