版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、MicrosoftCryptoAPI加密技术简介加密API在企业计算模型(EnterpriseComputingModel)中有着重要的应用。企业计算化程度意味着人的接触更全球化,例如国际商品贸易,州际库存管理等等。在这些领域中经常要通过不安全渠道传输敏感信息例如电传合同,通过电子邮件收发订单,及种种其它情况。使用加密API(CryptographyAPI),你就能够保证信息的安全性。加密API总览加密服务提供者模块(CryptographyServiceProviderCSP)当对用户的私有敏感数据提供保护时,加密API中的函数允许应用程序以一种灵活的方式来加密或者电子签名数据。所有加密操作
2、都由独立的模块来实施,这些模块叫作加密服务提供者(cryptographicserviceprovider)。操作系统中已经包含了一个CSP,名叫“MicrosoftRSABaseProvider”。每个CSP都对加密API层提供一个不同的实现。一些提供强加密算法,而另一些会包含如智能卡(smartcards,智能卡是一张嵌有包含用户安全信息芯片的塑料卡片)之类的硬件部件。另外,一些CSP可能会直接与用户交互,如使用用户的签名私鈅进行数据签名时。应用程序不要使用依赖于特定CSP的属性。例如,“MicrosoftRSABaseProvider”目前使用40位的会话密鈅(sessionkeys)和
3、512位的公鈅(publickeys)。当程序维护这些的时候,要小心的不要假定需要使用多大的内存去存储它们。另外,当用户在系统中安装一个不同的CSP后,程序很可能出错。你要努力使写出的程序尽可能的well-behavedandflexible(行为良好且易扩展)。密鈅库每个CSP都有一个密鈅库(keydatabase),里面存储着由CSP保存的算法密鈅。每个密鈅库都包含一个或多个密鈅容器(keycontainer),每个容器都包含所有属于特定用户(或使用加密API的客户端程序)的密鈅对。每个密鈅容器都被赋与一个唯一的名字,这个名字是程序要获得此容器句柄时传给函数CryptAcquireCont
4、ext的参数。加密当进行数据加密时,明文消息(plain-textmessage)在被编码后会看起来象完全随机的二进制数据,以至于没有密鈅就很难将其转化为原来的消息。本文中使用如下定义:消息(Message):指任何数据块。消息可以是ASCII文本,一个数据库文件或者任何你要安全存储或者传输的数据。明文(Plaintext):指没有被加密的数据。密文(Ciphertext):指被加密过的数据。一旦消息被加密,它就可以存储在非安全的介质上或者通过非安全的网络传输而仍然保持安全。之后,消息可以解密回原来的格式。当加密消息时,要使用加密密鈅(encryptionkey)。这就类型于用一把钥匙去锁一把
5、锁一样。当解密这个消息时,必须用相应的解密密鈅(decryptionkey)。对解密密鈅的严格限制访问非常重要,因为任何拿到它的人可以解开用相应的加密密鈅加密的所有消息。真正的难点是安全的保存密鈅和安全的将密鈅传输到其它人那。有两种主要的加密算法:对称算法(symmetricalgorithms)与公鈅算法(public-keyalgorithms)也叫做非对称算法(asymmetricalgorithms)。使用对称算法的系统有时归入传统型(conventional)中。算法对称算法是最普遍的加密算法类型。它们叫“对称”是因为使用相同的密鈅进行加密与解密。与使用公鈅算法的密鈅不同,对称密鈅是
6、经常变化的。因为这个原因,此处将它们归于会话密鈅。与公鈅算法相比,对称算法非常快,因此最适于加密大量数据的情况。一些最常用的对称加密算法是RC2,RC4,与数据加密标准(DataEncryptionStandard,DES)。(译注:单重DES因密鈅长度已不适应当前的加密环境,最好不用。可以使用三重DES,或者AES)公鈅(非对称)算法使用一对不同的密鈅:一个公鈅和一个私鈅。私鈅由密鈅对的所有者自己保存,公鈅可以自由分发给所有要求得到的人。如果用一个密鈅加密一个消息,必须用另一个密鈅解密此消息。公鈅算法很慢,要比对称算法慢数千倍。因此它们一般仅用来加密会话密鈅。它们也用来对消息进行数字签名(d
7、igitallysign),下一部分会讨论这个内容。最常用的公鈅加密算法之一是RSAPublic-KeyCipher。文件签名数字签名(Digitalsignatures)用在你要以明文形式分发一个消息,并且你想要让接收者能够验证这个消息自从离开你手后没有被篡改过。对消息签名并不会改变消息,它仅生成一个可附着在消息上或者单独传输的数字签名。数字签名使用公鈅算法生成。使用私鈅来生成,并且使用相对应的公鈅来验证。几个加密API函数初始化CSP:CryptAcquireContext,CryptReleaseContext函数CryptAcquireContext用来获得CSP中一个特定密鈅容器的句
8、柄。返回的句柄然后就可以对选择的CSP进行调用。函数CryptReleaseContext用于释放函数CryptAcquireContext返回的句柄。CryptReleaseContext不会删除任何CryptographyAPI对象,它仅仅释放对象的句柄。函数CryptAcquireContext执行两个操作。首先试着查找变量中指定的CSP,如果找到,函数试着查找CSP中匹配指定密鈅容器名的密鈅容器。此函数也可以用于建立、删除密鈅容器,这取决于函数中的参数值。取得默认CSP中默认密鈅容器的代码如下所示:#include/对CryptoAPI的定义/*对于非C/C+用户,此处用到的常量如下:
9、#defineMS_DEF_PROVMicrosoftBaseCryptographicProviderv1.0#definePROV_RSA_FULL1*/BOOLbResult;HCRYPTPROChProv;/试图取得转为密鈅容器的句柄bResult=CryptAcquireContext(&hProv,/保存返回句柄的变量NULL,/默认密鈅容器MS_DEF_PROV,/默认CSPPROV_RSA_FULL,/要取得的CSP类型0);/未指定动作/在此处执行操作/释放容器句柄CryptReleaseContext(hProv);如果CryptAcquireContext调用成功,返回值
10、非零,变量hProv即为要取得的密鈅容器句柄。要在默认CSP中添加或者创建一个密鈅容器,要写的代码如下:#include/对CryptoAPI的定义/*对于非C/C+用户,此处用到的常量如下:#defineMS_DEF_PROVMicrosoftBaseCryptographicProviderv1.0#definePROV_RSA_FULL1#defineCRYPT_NEWKEYSET0 x8*/BOOLbResult;HCRYPTPROChProv;/试图添加一个新的密鈅容器BResult=CryptAcquireContext(&hProv,/保存返回句柄的变量NULL,/默认密鈅容器M
11、S_DEF_PROV,/默认CSPPROV_RSA_FULL,/要取得的CSP类型CRYPT_NEWKEYSET);/创建一个新密鈅容器./在此处执行操作./释放容器句柄CryptReleaseContext(hProv);如果CryptAcquireContext调用成功,返回值非零,变量hProv即为新的密鈅容器句柄。要从默认CSP中删除一个存在的密鈅容器,要写的代码如下:#include/对CryptoAPI的定义/*对于非C/C+用户,此处用到的常量如下:#defineMS_DEF_PROVMicrosoftBaseCryptographicProviderv1.0#definePRO
12、V_RSA_FULL1#defineCRYPT_DELETEKEYSET0 x10*/BOOLbResult;HCRYPTPROChProv;/试图删除密鈅容器BResult=CryptAcquireContext(&hProv,/保存返回句柄的变量NULL,/默认密鈅容器MS_DEF_PROV,/默认CSPPROV_RSA_FULL,/要取得的CSP类型/释放散列对象/获得散列对象句柄CRYPT_DELETEKEYSET);/删除存在的密鈅容器如果CryptAcquireContext调用成功,返回值非零,变量hProv指向的密鈅容器已经删除,此密鈅容器不再有效。散列数据:CryptCrea
13、teHash,CryptHashData,CryptGetHashParam,CryptDestroyHash当我说“散列法”或“散列”(hashingorhash)时,是指从一块数据中派生出一个数值的方法或算法。这可能是简单的将所有数据位相加,或复杂到要对数据进行傅立叶变换。(译注:散列也被称为哈希,杂凑)上面列出的四个函数是用于创建或者维护从提供的数据生成的散列值的,一般一起使用:函数CryptCreateHash用于散列数据时初始化。它返回CSP散列对象的句柄,此句柄会在后续CryptHashData函数散列数据时使用。下一步是调用CryptGetHashParam函数取得散列值。函数C
14、ryptDestroyHash释放函数CryptCreateHash返回的句柄。CryptDestroyHash不会删除任何加密API对象,它仅仅释放散列对象的句柄。CryptHashData函数用来从提供的数据中计算密码散列。为计算一个大数据块或者数据块的几个部分时,此函数可被调用多次。例如,我们要对缓冲区pBuffer中dwBufferLen字节长的数据进行散列。在此例子中我仅使用CALG_MD5散列算法来实现此目的。加密APISDK文档中还提供对许多其它算法详细的描述。本例子假定只散列一块数据。一旦调用CryptGetHashParam函数取得了散列值,此散列实例对象便不能再散列其它数据
15、了。#include/对CryptoAPI的定义/*对于非C/C+用户,此处用到的常量如下:#defineALG_CLASS_HASH(413)#defineALG_TYPE_ANY(0)#defineALG_SID_MD53#defineCALG_MD5(ALG_CLASS_HASH|ALG_TYPE_ANY|ALG_SID_MD5)#defineHP_HASHVAL0 x0002/散列值#defineHP_HASHSIZE0 x0004/散列值长度*/BOOLbResult;HCRYPTHASHhHash;DWORDdwBufferSize;DWORDdwValue;PBYTEpBuffe
16、r;bResult=CryptCreateHash(hProv,/之前获得的CSP句柄CALG_MD5,/散列算法0,/非密鈅散列0,/置0&hHash);/保存散列对象句柄的变量/散列数据bResult=CryptHashData(hHash,/散列对象句柄pBuffer,/数据缓冲区指针dwBufferlen,/数据长度0);/未指定值/得到散列值尺寸dwBufferSize=sizeof(DWORD);bResult=CryptGetHashParam(hHash,/散列对象句柄HP_HASHSIZE,/得到散列值尺寸&dwValue,/保存散列值长度缓冲区&dwBufferSize,/
17、缓冲区长度0);/必须置0/创建保存散列值的缓冲区pBuffer=newchardwBufferSize;/Gethashvalue.bResult=CryptGetHashParam(hHash,/散列对象句柄HP_HASHVAL,/得到散列值pBuffer,/保存散列值长度缓冲区&dwBufferSize,/缓冲区长度0);/必须置0CryptDestroyHash(hHash);上面例子为pBuffer指向的数据生成一个散列值。如果还要散列其它数据,用这个数据调用CryptHashData,产生的散列值仍会是原来的值。已警告过一使用HP_HASHVALUE参数调用CryptGetHash
18、Param会阻止使用此对象继续进行散列。生成密鈅:CryptDeriveKey,CryptGenKey,CryptDestroyKey这三个函数用来产生密鈅句柄:CryptDeriveKey函数从一个指定的密码(password)产生密鈅。CryptGenKey函数从一个随机产生的数值产生密鈅。CryptDestroyKey函数释放密鈅对象。使用CryptGenKey函数时,建议使用CRYPT_EXPORTABLE参数以创建一个可导出的会话密鈅。这会建立一个可从一台机器移到另一台机器的值。不提供此参数,返回值仅在此机器/会话中有效。下面是如何使用CryptDeriveKey函数的例子,假定pP
19、assword指向一个用户指定的密码,dwPasswordLength为密码长度。#include/对CryptoAPI的定义/*对于非C/C+用户,此处用到的常量如下:#defineALG_CLASS_HASH(413)#defineALG_TYPE_ANY(0)#defineALG_SID_MD53#defineCALG_MD5(ALG_CLASS_HASH|ALG_TYPE_ANY|ALG_SID_MD5)#defineCRYPT_EXPORTABLE0 x00000001#defineALG_CLASS_DATA_ENCRYPT(313)#defineALG_TYPE_STREAM(4
20、9)#defineALG_SID_RC22#defineCALG_RC4(ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_RC4)*/BOOLbResult;HCRYPTHASHhHash;HCRYPTKEYhKey;/释放密鈅对象/获得散列对象句柄bResult=CryptCreateHash(hProv,/之前获得的CSP句柄CALG_MD5,/散列算法0,/非密鈅散列0,/置0&hHash);/保存散列对象句柄的变量/散列数据bResult=CryptHashData(hHash,/散列对象句柄pPassword,/指向密码的指针dwPass
21、wordLength,/数据长度0);/未指定值/从指定的密码产生密鈅bResult=CryptDeriveKey(hProv,/之前获得的CSP句柄CALG_RC4,/流加密hHash,/密码散列后对象句柄CRYPT_EXPORTABLE,/密鈅可导出&hKey);/保存密鈅对象句柄的变量/用密鈅进行操作/释放散列对象CryptDestroyHash(hHash);CryptDestroyKey(hKey);/加密数据加密与解密数据:CryptEncrypt,CryptDecrypt简单来说,尽管不全对,加密API处理数据是围绕两个函数一加密(CryptEncrypt)与解密(CryptDe
22、crypt)。这两个函数非常易用,但需要对其参数进行一下说明:每个函数的头六个参数是相同的头两个参数仅是密鈅句柄和一个可选的散列对象第三个参数是一个布尔值,此值在最后一块数据块之前保持为FALSE,为让函数对最后一块数据进行特殊处理,在最后一块数据时置为TRUE第四与第五个参数是标志值和一个指向加密或解密数据的指针第六个参数是缓冲区中待加密字符的数量第七个参数通常与第六个参数相同,它指出数据块长度。这是因为对于许多算法来说,加密数据尺寸与解密数据尺寸是相同的。然而,某些算法增加加密数据的长度。在这种情况下,第五个参数中的缓冲区必须大到足以容纳额外的数据。缓冲区长度的问题可以在加密前通过调用Cr
23、yptEncrypt函数返回需要缓冲区的尺寸来解决。下面的例子代码演示了这种技术。在这个例子中,某些值已假定之前已获得,我们仅要加密pData指向的缓冲区中dwDataLen字节长的数据。BOOLbResult;PBYTEpBuffer;DWORDdwSize;/将缓冲中数据长度赋给变量dwSize=dwDataLen;/让API返回给我们需要的缓冲长度bResult=CryptEncrypt(hKey,/之前获得的密鈅对象0,/不散列数据TRUE,/最后的还是缓冲的数据0,/必须置0NULL,/无数据,简单的返回尺寸&dwSize,/数据的尺寸dwSize);/数据块尺寸/现在得到了输出缓冲
24、区尺寸,创建此缓冲区pBuffer=newchardwSize;bResult=CryptEncrypt(hKey,/之前获得的密鈅对象0,/不散列数据TRUE,/最后的还是缓冲的数据0,/必须置0pBuffer,/数据缓冲区&dwSize,/数据尺寸dwSize);/数据块尺寸同时进行加密与解密当使用同一个密鈅进行加密或解密两个数据流时,必须采取一些措施。同一个物理会话密鈅不得被用于同一个操作,因为每个会话密鈅容器的内部状态信息在同时进行一个操作时会混乱。对此问题的简单解决办法是制作一份会话密鈅的拷贝。这样,原始密鈅进行一个操作,拷贝密鈅进行另一个操作。制作一个会话密鈅的拷贝可以通过调Cry
25、ptExportKey导出密鈅,然后调CryptlmportKey将它导进来。密鈅导入后,CSP会给这个“新”的密鈅分配自己的内部内存区域,就好象它跟原来的密鈅完全没有关联一样。CRYPTOAPI例程程序有下列命令行结构。Usage:EncryptswitchargumentsWhereswitchandoptionalargumentsareoneof:SwitchArgumentsDescription/ADDUSERtoaddusertoCSPtable/REMOVEUSERtoremoveuserfromCSPtable/ENCRYPTufefpwdtoencryptafile/DEC
26、RYPTefufpwdtodecryptafile/SIGNufsfdesctosignafile/VERIFYufsfdesctoverifyasignedfile/CSPtoshowCSPstatisticsanduf=nameofanunencryptedfileef=nameofanencryptedfilesf=nameofasignedfilepwd=optionalpassworddesc=optionalsignaturedescription编码问题需要显式地在例程中定义特定的常量,因为加密API头文件(wincrypt.h)使用_WIN32_WINNT常量来检测正在使用哪个
27、WindowsNT版本。当写此例程时,此常量尽管需要,但当前的编译器仍然未定义它。定义此常量代码才不会编译出错,可以在以后的编译器定义它后再将其移除。API函数CryptAcquireContext有一个未文档化的常量值MS_DEF_PROV。这个常量用来指代默认CSP。这个值用在/ADDUSER命令行开关中。这允许程序使用任何已安装的CSP,不需要知道其名字。增加或者删除一个用户/ADDUSER与/REMOVERUSER开关用来增加或删除一个默认的加密客户端。为使其它加密功能运行正常,/ADDUSER开关必须首先被调用。下面一系列操作会被执行:一个默认密鈅容器被创建一个数字签名密鈅对在密鈅容器中被创建一个密鈅交换密鈅对在密鈅容器中被创建这项操作仅需执行一次,除非操作系统重装。假如默认的密鈅容器与密鈅对已经创建,那么再次使用这个开关没有效果。从命令行运行/ADDUSER开关如下:Encrypt/ADDUSER从命令行运行/REMOVEUSER开关如下:Encrypt/REMOVEUSER加密或解密文件/ENCRYPT开关用来加密文件。通过这个开关加密的文件以后可以通过/DECRYPT开关解密。注意:为了给默认用户创建一个密鈅容器,必须在进行任何加密前调用/ADDUSER开关。从命令行运行/ENCRYPT开关如下:Encrypt/encryptvso
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业人才选拔评估标准工具包
- 销售谈判策略与技巧学习资料库
- 家用电器售后质量保证承诺书(6篇)
- 行业技术创新支持承诺书(3篇)
- 露营帐篷夜间安全照明方案
- 质量管理与改进措施实施声明书5篇
- 绿色建筑质量承诺保证承诺书(8篇)
- 市场营销活动策划方案执行检查清单
- 服务品质持续保障承诺书5篇
- 2026年柴油机买卖合同
- 2026河北邯郸市检察机关聘用制书记员招考44人笔试模拟试题及答案解析
- 2026年安徽中澳科技职业学院单招综合素质考试题库含答案详解(夺分金卷)
- 无损检测质量考核制度
- 新苏教版科学三年级下册第4课《天气预报》教学课件
- 卫生院单位预算管理制度
- 中国大唐集团招聘笔试题库2026
- 高速公路改扩建工程监理投标方案(技术方案)
- 2026年陕西单招职业技能测试要点含答案
- 2025年延安事业单位真题
- 初中语文八年级上册《春望》教学设计
- ppe-安全知识培训课件
评论
0/150
提交评论