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

来源:互联网 发布:java编写九九乘法表 编辑:程序博客网 时间:2024/05/19 18:44

文章中罗列了自己在练习使用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.hstdafx.cpp预处理文件到FileView中。最好从其它项目中直接复制过来,将本项目中用不到的内容删除在CryptErr.cppCencrypt.cppmain.cpp文件最顶部添加预处理头文件#include "stdafx.h"

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

#ifndef _WIN32_WINNT

#define _WIN32_WINNT 0x0400

#endif

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

#define _WIN32_WINNT 0x0400

 5、程序在显示CSPCencrypt类有一错误,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。从网上搜集的具体操作系统对应关系如下:

Windows Server 2003 family: _WIN32_WINNT>=0x0502    WINVER>=0x0502Windows XP:                    _WIN32_WINNT>=0x0501    WINVER>=0x0501Windows 2000:                  _WIN32_WINNT>=0x0500    WINVER>=0x0500Windows NT 4.0:                _WIN32_WINNT>=0x0400    WINVER>=0x0400Windows Me:                    _WIN32_WINDOWS=0x0500    WINVER>=0x0500Windows 98:                    _WIN32_WINDOWS>=0x0410    WINVER>=0x0410Windows 95:                   _WIN32_WINDOWS>=0x0400    WINVER>=0x0400Internet 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

问题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即可。