当前位置: 首页 > 图文教程 > 开发语言 > VC++ > Microsoft CryptoAPI加密技术(二)

VC++
宏的妙用
泛型编程与设计新思维
C++中的虚函数(一)
C++模板元编程
C++多态技术
通用结构复制函数
<C++实践系列>C++中的虚函数(virtual function)
<C++实践系列>C++中的引用(reference)
<C++实践系列>C++中的异常(exception)
<C++实践系列>C++中的模板(template)
构造函数中的this指针
串行化(Serialization)
二进制浏览、编辑的实现
介绍一个模板动态数组
VC++界面一揽子解决方案(第三版) 介绍
VC++通用GIS功能开发解决方案 2.0v 介绍
确定有穷自动机分析内核
委托、信号和消息反馈的模板实现技术
按照类型名称动态创建对象
Boost中应用的泛型编程技术

VC++ 中的 Microsoft CryptoAPI加密技术(二)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 143 ::
收藏到网摘: n/a

Microsoft CryptoAPI加密技术(二)
作者:Cuick

下载本文示例源代码

上次我们讲了Microsoft CryptoAPI的构成以及会话密钥的使用。接下来我们将看一下公私密钥对的使用、HASH算法、数字签名等技术。

一、 公用密钥加密技术

公用密钥加密技术使用两个不同的密钥:公钥和私钥。私钥必须安全的保管好不能被外人知道,而公钥可以告诉任何人,只要他需要。通常公钥是以数字证书的形式发布的。
用公私密钥对中的一个密钥加密的数据只能用密钥对中的另一个密钥才能解密。也就是说用用户A的公钥加密的数据只能用A的私钥才能解密,同样,用A的私钥加密的数据只能用A的公钥才能解密。
如果用私钥签名一个消息,那么必须用与之对应的公钥去验证签名的有效性。
不幸的是公用密钥加密技术的效率非常低甚至只有对称加密的千分之一,所以不适合对大量的数据进行加密。实际上,公用密钥加密技术一般用来加密会话密钥,而数据加密可以用对称加密的方法。
好了,让我们回到Microsoft CryptoAPI。我们知道一个CSP有一个密钥库,这个密钥库有一个或多个密钥容器。而密钥容器中有什么呢?一般来说,一个密钥容器中有两对公私密钥对,一对用来加密会话密钥,而另一对用来进行数字签名,也就是大家知道的key exchange key pair和signature key pair。

那么,怎么得到这些密钥对呢?

if(CryptGetUserKey( hCryptProv, // 我们已经得到的CSP句柄 AT_SIGNATURE, // 这里想得到signature key pair &hKey)) // 返回密钥句柄{ printf("A signature key is available.\n");}else	//取signature key pair错误{ printf("No signature key is available.\n"); if(GetLastError() == NTE_NO_KEY) //密钥容器里不存在signature key pair { // 创建 signature key pair. printf("The signature key does not exist.\n"); printf("Create a signature key pair.\n"); if(CryptGenKey( hCryptProv,	//CSP句柄 AT_SIGNATURE,	//创建的密钥对类型为signature key pair 0,	//key类型,这里用默认值 &hKey))	//创建成功返回新创建的密钥对的句柄 { printf("Created a signature key pair.\n"); } else { printf ("Error occurred creating a signature key.\n"); } } else { printf ("An error other than NTE_NO_KEY getting signature\key.\n"); }} // end if
将参数AT_SIGNATURE换成AT_KEYEXCHANGE就可以得到key exchange key pair。
现在我们得到的仅仅是一个句柄,我们需要把这个key值存储的磁盘或文件中,这样才能传给对方来进行解密。下面让我们来看一个用于导出密钥的API。
BOOL WINAPI CryptExportKey( HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE* pbData, DWORD* pdwDataLen);
hKey:需要被导出的密钥句柄

hExpKey:前面咱们提到公用密钥加密技术的效率非常低所以公用密钥加密技术
一般用来加密会话密钥。这里传入的密钥就是用来加密被导出的密钥
的。也就是说,被导出的密钥hKey的数据是经过这个密钥hExpKey
加密的。如果为NULL表示不经过加密直接导出。

dwBlobType:被导出的密钥类型,比如公钥还是私钥等

dwFlags:标志位

pbData:保存导出的数据,如果为NULL, pdwDataLen将返回导出数据的长度

pdwDataLen:输入pbData缓冲区的大小,输出导出数据的长度

下面的例子演示如何导出密钥。

if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB,	//导出公钥 0, NULL, &dwBlobLen))	//返回密钥数据长度{ printf("Size of the BLOB for the public key determined. \n");}else{ printf("Error computing BLOB length.\n"); exit(1);}//--------------------------------------------------------------------// Allocate memory for the pbKeyBlob.if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) { printf("Memory has been allocated for the BLOB. \n");}else{ printf("Out of memory. \n"); exit(1);}//--------------------------------------------------------------------// Do the actual exporting into the key BLOB.if