Microsoft CryptoAPI加密技术(二)

2016-01-29 12:12 11 1 收藏

Microsoft CryptoAPI加密技术(二),Microsoft CryptoAPI加密技术(二)

【 tulaoshi.com - C语言心得技巧 】

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

下载本文示例源代码

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

一、 公用密钥加密技术

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

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

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 signaturekey.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
                        

来源:http://www.tulaoshi.com/n/20160129/1485092.html

延伸阅读
标签: windows系统
Win8.1系统休眠唤醒加密技巧   在使用过程中,我们会发现Win8.1系统休眠后,唤醒不提示输入密码,直接进入系统,感觉不是很安全。下面图老师小编就为大家介绍一下Win8.1系统休眠唤醒加密技巧! 1.移动鼠标到屏幕右上角,会出现超级按钮,选择设置; 2.在设置中,选择右下角的更改电脑设置; 3.点开后,点击左侧的账...
名称空间与程序集名称之间有什么区别? 名称空间是类型的一种逻辑命名方案,其中简单类型名称(如 MyType)前面带有用点分隔的层次结构名称。这样的命名方案完全在开发人员的控制之下。例如,键入 MyCompany.FileAccess.A 和 MyCompany.FileAccess.B 在逻辑上将会具有与文件访问相关的功能。.NET 框架使用一种层次结构命名方案,用于将类型按相...
Microsoft的ACCESS数据库,是我们常用的桌面数据之一,大多中小企业的数据库管理系统都可以采用它,但其安全性一直令人担犹,试想,一套财务管理系统,用户直接打开数据库去更改数据,后果会如何?有些系统对ACCESS数据库可能只是更改扩展名,或加个密码,众所周知,破解ACCESS密码的方法和工具网上多的是!所以这样的加密一样令人担犹,下面介...
标签: ASP
  如果要在同一台计算机上安装SQL Server 7.0企业版和微软其它服务器产品如IIS 、Exchange 等时,有何建议安装程序? 基本上为了性能的考虑不建议您将数种服务器应用程序与SQL Server安装在同一台计算机上。如果真的有此需求,请依照下列顺序安装: 安装Windows NT Server企业版﹝此版本已包含Service Pack 3,请注意不要安装IIS﹞。 ...
名称空间与程序集名称之间有什么区别? 名称空间是类型的一种逻辑命名方案,其中简单类型名称(如 MyType)前面带有用点分隔的层次结构名称。这样的命名方案完全在开发人员的控制之下。例如,键入 MyCompany.FileAccess.A 和 MyCompany.FileAccess.B 在逻辑上将会具有与文件访问相关的功能。.NET 框架使用一种层次结构命名方案,用于将类型按相...

经验教程

571

收藏

44
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部