您的位置:首页 > 编程语言

CSP编程基础--CryptAPI使用过程中碰到的问题

2014-09-24 09:34 399 查看
文章中罗列了自己在练习使用CryptAPI各种函数的过程中所碰到的各种问题,因此文章并没有特定的组织结构。

问题1:在学习CryptAPI的开始是去MSDN上找的范例http://msdn.microsoft.com/en-us/library/ms867086.aspx,其中包含实例源代码的下载Down
5003.exe,这应该是最为权威的CryptAPI函数使用教程,下载下来以后会发现在环境VC6.0 SP5 + WinXP SP3 下难以编译通过,需要做如下修改后才可以直接运行。

解决办法:

直接下载经过本人修改后的程序CryptAPI函数调用实例(修改后),下载后可直接在VC6.0
SP5环境下运行。否则按照下面步骤一步步修改即可。

1、运行下载后的ZIP自解压文件,将代码解压到工作目录中,使用VC6打开Encrypt.mdp,提示需要将项目文件转换为VS6的格式

2、将CryptErr.cpp文件从FileView中删除后,再重新引入,解决项目文件中此文件引用错误的问题

3、手工创建并添加stdafx.h与stdafx.cpp预处理文件到FileView中。最好从其它项目中直接复制过来,将本项目中用不到的内容删除在CryptErr.cpp、Cencrypt.cpp、main.cpp文件最顶部添加预处理头文件#include
"stdafx.h"

4、将CryptErr.h文件中,定义NT版本的定义删除

#ifndef _WIN32_WINNT

#define _WIN32_WINNT 0x0400

#endif

在stdafx.h中添加对NT版本的定义

#define _WIN32_WINNT 0x0400

5、程序在显示CSP时Cencrypt类有一错误,CEncrypt::Statistics()函数中

将语句

if (!::CryptGetProvParam(this->m_hCryptProvider, PP_ENUMALGS, pbData, &dwDataLen, 0))

中最后参数0改为dwFlags,修改后语句如下:

if (!::CryptGetProvParam(this->m_hCryptProvider, PP_ENUMALGS, pbData, &dwDataLen, dwFlags))

6、运行程序,并使用各个开关查看运行结果

备注:此程序运行通过后会在"工程目录\Debug\Encrypt.exe"可执行文件。如需要使用此程序,则需要在cmd窗口执行此文件,并使用提示给出的参数即可。(如图示加密文件D:\t.txt后将加密文件保存为D:\e.txt,密码为123)



问题2:在VC6.0编译环境下,在确保程序没有错误的情况下会碰到各种编译问题,例如缺少链接库,类型为定义等问题,主要问题在于VC6.0的编译器采用的标准太旧导致CryptAPI编译出错,因此在运行CryptAPI之前,要做好环境的设置。

解决办法:

最好的解决办法就是使用VS2005以上的版本作为自己的编译环境。如若使用VC6.0作为编译环境,则需要做如下工作;

1、首先需要Crypt32.lib,将它加到project->setting->link下面,当然你也可以在程序中用#pragma comment (lib, "crypt32.lib")加入。

2、在程序开头,你要加入两个头文件 windows.h 和 wincrypt.h,和一个#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

注意添加<windows.h>一定要在<wincrypt.h>之前,因为在<wincrypt.h>编译的过程中大量的引用了<windows.h>

当包含wincrypt.h头文件时,一般都需要定义#define _WIN32_WINNT 0xxx(具体的值),否则将得到如下错误:error C2065: undeclared identifier,不同的操作系统会有不同定义,我的操作环境 VC6.0 + win XP 设置为 #define _WIN32_WINNT 0400。从网上搜集的具体操作系统对应关系如下:

[cpp] view
plaincopy

<span style="font-family: 'Microsoft YaHei'; "><span style="font-size:18px;">Windows Server 2003 family: _WIN32_WINNT>=0x0502 WINVER>=0x0502

Windows XP: _WIN32_WINNT>=0x0501 WINVER>=0x0501

Windows 2000: _WIN32_WINNT>=0x0500 WINVER>=0x0500

Windows NT 4.0: _WIN32_WINNT>=0x0400 WINVER>=0x0400

Windows Me: _WIN32_WINDOWS=0x0500 WINVER>=0x0500

Windows 98: _WIN32_WINDOWS>=0x0410 WINVER>=0x0410

Windows 95: _WIN32_WINDOWS>=0x0400 WINVER>=0x0400

Internet Explorer 6.0: _WIN32_IE>=0x0600

Internet Explorer 5.6: _WIN32_IE>=0x0560

Internet Explorer 5.01, 5.5: _WIN32_IE>=0x0501

Internet Explorer 5.0, 5.0a, 5.0b: _WIN32_IE>=0x0500

Internet Explorer 4.01: _WIN32_IE>=0x0401

Internet Explorer 4.0: _WIN32_IE>=0x0400

Internet Explorer 3.0, 3.01, 3.02: _WIN32_IE>=0x0300</span></span>

问题3: 如果使用VS2005作为自己的编译工具,在每个项目调试时会提示:无法找到“XXX.exe”的调试信息。

解决办法:

首先打开菜单 项目->项目属性页

1. 选择 配置属性->链接器->调试->生成调试信息 改为 是

2. 选择 配置属性->C/C++ ->常规->调试信息格式 改为 用于“编辑并继续”的程序数据库(/ZI)

3. 选择 配置属性->C/C++ ->优化->优化 改为 禁用(/Od)

问题4: 在使用USBkey等内嵌CSP的硬件设备时,如何查看所连接电脑是否已经将内嵌CSP注册于本机中?

解决办法:

可以查看注册表

CryptoAPI的配置信息存储在注册表中,包括如下表目:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft \ Cryptography \Defaults

HKEY_CURRENT_USER\ Software \ Microsoft\ Cryptography \Providers

问题05: 调试时出现提示:error LNK2019: 无法解析的外部符号 __imp__CertCloseStore@8,该符号在函数 _main 中被引用。

解决办法:

一般出现lnk2019错误都是库文件没添加造成的。(如何寻找缺失的具体哪个库?可以在MSDN中搜索函数名称,查找到函数相关的库)

可以使用语句“#pragma comment (lib, "XXXX.lib")”

或者

项目--》属性--》配置属性--》链接器--》输入--》附加依赖项。在其中加入所需库文件,同时在“链接器--》常规--》附加库目录”中填入相应库名。



问题06:在调试程序的时候,设置了断点,在启动调试后断点失效,显示为空心断点并由黄色感叹号标注,并给予提示:难以命中断点,原因是编译器或者调试器优化等。

解决办法:

该问题的情况很复杂,可能导致此问题的一个原因为程序的编译为Release,而不是Debug模式,需要将编译模式更改为Debug即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: