Microsoft CryptoAPI加密技术_第1页
Microsoft CryptoAPI加密技术_第2页
Microsoft CryptoAPI加密技术_第3页
Microsoft CryptoAPI加密技术_第4页
Microsoft CryptoAPI加密技术_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

MicrosoftMicrosoft CryptoAPICryptoAPI 加密技术加密技术 简介简介 加密 API 在企业计算模型 Enterprise Computing Model 中有着重要的应用 企业计算化程度意味着人的接触更全球化 例如国 际商品贸易 州际库存管理等等 在这些领域中经常要通过不安全渠道传输敏感信息 例如电传合同 通过电子邮件收发订单 及种种 其它情况 使用加密 API Cryptography API 你就能够保证信息的安全性 加密加密 APIAPI 总览总览 加密服务提供者模块 Cryptography Service Provider CSP 当对用户的私有敏感数据提供保护时 加密 API 中的函数允许应用程序以一种灵活的方式来加密或者电子签名数据 所有加密操作 都由独立的模块来实施 这些模块叫作加密服务提供者 cryptographic service provider 操作系统中已经包含了一个 CSP 名叫 Microsoft RSA Base Provider 每个 CSP 都对加密 API 层提供一个不同的实现 一些提供强加密算法 而另一些会包含如智能卡 smartcards 智能卡是一张嵌有 包含用户安全信息芯片的塑料卡片 之类的硬件部件 另外 一些 CSP 可能会直接与用户交互 如使用用户的签名私鈅进行数据签名时 应用程序不要使用依赖于特定 CSP 的属性 例如 Microsoft RSA Base Provider 目前使用 40 位的会话密鈅 session keys 和 512 位的公鈅 public keys 当程序维护这些的时候 要小心的不要假定需要使用多大的内存去存储它们 另外 当用户在系统中 安装一个不同的 CSP 后 程序很可能出错 你要努力使写出的程序尽可能的 well behaved and flexible 行为良好且易扩展 密鈅库密鈅库 每个 CSP 都有一个密鈅库 key database 里面存储着由 CSP 保存的算法密鈅 每个密鈅库都包含一个或多个密鈅容器 key container 每个容器都包含所有属于特定用户 或使用加密 API 的客户端程序 的密鈅对 每个密鈅容器都被赋与一个唯一的名字 这个名字是程序要获得此容器句柄时传给函数 CryptAcquireContext 的参数 加密加密 当进行数据加密时 明文消息 plain text message 在被编码后会看起来象完全随机的二进制数据 以至于没有密鈅就很难将其 转化为原来的消息 本文中使用如下定义 消息 Message 指任何数据块 消息可以是 ASCII 文本 一个数据库文件或者任何你要安全存储或者传输的数据 明文 Plain text 指没有被加密的数据 密文 Cipher text 指被加密过的数据 一旦消息被加密 它就可以存储在非安全的介质上或者通过非安全的网络传输而仍然保持安全 之后 消息可以解密回原来的格式 当加密消息时 要使用加密密鈅 encryption key 这就类型于用一把钥匙去锁一把锁一样 当解密这个消息时 必须用相应 的解密密鈅 decryption key 对解密密鈅的严格限制访问非常重要 因为任何拿到它的人可以解开用相应的加密密鈅加密的所有消 息 真正的难点是安全的保存密鈅和安全的将密鈅传输到其它人那 有两种主要的加密算法 对称算法 symmetric algorithms 与公鈅算法 public key algorithms 也叫做非对称算法 asymmetric algorithms 使用对称算法的系统有时归入传统型 conventional 中 算法算法 对称算法是最普遍的加密算法类型 它们叫 对称 是因为使用相同的密鈅进行加密与解密 与使用公鈅算法的密鈅不同 对称密 鈅是经常变化的 因为这个原因 此处将它们归于会话密鈅 与公鈅算法相比 对称算法非常快 因此最适于加密大量数据的情况 一 些最常用的对称加密算法是 RC2 RC4 与数据加密标准 Data Encryption Standard DES 译注 单重 DES 因密鈅长度已不适 应当前的加密环境 最好不用 可以使用三重 DES 或者 AES 公鈅 非对称 算法使用一对不同的密鈅 一个公鈅和一个私鈅 私鈅由密鈅对的所有者自己保存 公鈅可以自由分发给所有要求得 到的人 如果用一个密鈅加密一个消息 必须用另一个密鈅解密此消息 公鈅算法很慢 要比对称算法慢数千倍 因此它们一般仅用 来加密会话密鈅 它们也用来对消息进行数字签名 digitally sign 下一部分会讨论这个内容 最常用的公鈅加密算法之一是 RSA Public Key Cipher 文件签名文件签名 数字签名 Digital signatures 用在你要以明文形式分发一个消息 并且你想要让接收者能够验证这个消息自从离开你手后没有 被篡改过 对消息签名并不会改变消息 它仅生成一个可附着在消息上或者单独传输的数字签名 数字签名使用公鈅算法生成 使用私鈅来生成 并且使用相对应的公鈅来验证 几个加密几个加密 APIAPI 函数函数 初始化初始化 CSPCSP CryptAcquireContext CryptAcquireContext CryptReleaseContextCryptReleaseContext 函数 CryptAcquireContext 用来获得 CSP 中一个特定密鈅容器的句柄 返回的句柄然后就可以对选择的 CSP 进行调用 函数 CryptReleaseContext 用于释放函数 CryptAcquireContext 返回的句柄 CryptReleaseContext 不会删除任何 Cryptography API 对象 它仅仅释放对象的句柄 函数 CryptAcquireContext 执行两个操作 首先试着查找变量中指定的 CSP 如果找到 函数试着查找 CSP 中匹配指定密鈅容器 名的密鈅容器 此函数也可以用于建立 删除密鈅容器 这取决于函数中的参数值 取得默认 CSP 中默认密鈅容器的代码如下所示 include 对 CryptoAPI 的定义 对于非 C C 用户 此处用到的常量如下 define MS DEF PROV Microsoft Base Cryptographic Provider v1 0 define PROV RSA FULL 1 BOOL bResult HCRYPTPROC hProv 试图取得转为密鈅容器的句柄 bResult CryptAcquireContext 未指定动作 在此处执行操作 释放容器句柄 CryptReleaseContext hProv 如果 CryptAcquireContext 调用成功 返回值非零 变量 hProv 即为要取得的密鈅容器句柄 要在默认 CSP 中添加或者创建一个密鈅容器 要写的代码如下 include 对 CryptoAPI 的定义 对于非 C C 用户 此处用到的常量如下 define MS DEF PROV Microsoft Base Cryptographic Provider v1 0 define PROV RSA FULL 1 define CRYPT NEWKEYSET 0 x8 BOOL bResult HCRYPTPROC hProv 试图添加一个新的密鈅容器 BResult CryptAcquireContext 创建一个新密鈅容器 在此处执行操作 释放容器句柄 CryptReleaseContext hProv 如果 CryptAcquireContext 调用成功 返回值非零 变量 hProv 即为新的密鈅容器句柄 要从默认 CSP 中删除一个存在的密鈅容器 要写的代码如下 include 对 CryptoAPI 的定义 对于非 C C 用户 此处用到的常量如下 define MS DEF PROV Microsoft Base Cryptographic Provider v1 0 define PROV RSA FULL 1 define CRYPT DELETEKEYSET 0 x10 BOOL bResult HCRYPTPROC hProv 试图删除密鈅容器 BResult CryptAcquireContext 删除存在的密鈅容器 如果 CryptAcquireContext 调用成功 返回值非零 变量 hProv 指向的密鈅容器已经删除 此密鈅容器不再有效 散列数据 散列数据 CryptCreateHash CryptCreateHash CryptHashData CryptHashData CryptGetHashParam CryptGetHashParam CryptDestroyHashCryptDestroyHash 当我说 散列法 或 散列 hashing or hash 时 是指从一块数据中派生出一个数值的方法或算法 这可能是简单的将 所有数据位相加 或复杂到要对数据进行傅立叶变换 译注 散列也被称为哈希 杂凑 上面列出的四个函数是用于创建或者维护从提供的数据生成的散列值的 一般一起使用 函数 CryptCreateHash 用于散列数据时初始化 它返回 CSP 散列对象的句柄 此句柄会在后续 CryptHashData 函数散列数据时使用 下一步是调用 CryptGetHashParam 函数取得散列值 函数 CryptDestroyHash 释放函数 CryptCreateHash 返回的句柄 CryptDestroyHash 不会删除任何加密 API 对象 它仅仅释放散 列对象的句柄 CryptHashData 函数用来从提供的数据中计算密码散列 为计算一个大数据块或者数据块的几个部分时 此函数可被调用多次 例 如 我们要对缓冲区 pBuffer 中 dwBufferLen 字节长的数据进行散列 在此例子中我仅使用 CALG MD5 散列算法来实现此目的 加密 API SDK 文档中还提供对许多其它算法详细的描述 本例子假定只散列一块数据 一旦调用 CryptGetHashParam 函数取得了散列值 此散列实例对象便不能再散列其它数据了 include 对 CryptoAPI 的定义 对于非 C C 用户 此处用到的常量如下 define ALG CLASS HASH 4 13 define ALG TYPE ANY 0 define ALG SID MD5 3 define CALG MD5 ALG CLASS HASH ALG TYPE ANY ALG SID MD5 define HP HASHVAL 0 x0002 散列值 define HP HASHSIZE 0 x0004 散列值长度 BOOL bResult HCRYPTHASH hHash DWORD dwBufferSize DWORD dwValue PBYTE pBuffer 获得散列对象句柄 bResult CryptCreateHash hProv 之前获得的 CSP 句柄 CALG MD5 散列算法 0 非密鈅散列 0 置 0 保存散列对象句柄的变量 散列数据 bResult CryptHashData hHash 散列对象句柄 pBuffer 数据缓冲区指针 dwBufferlen 数据长度 0 未指定值 得到散列值尺寸 dwBufferSize sizeof DWORD bResult CryptGetHashParam hHash 散列对象句柄 HP HASHSIZE 得到散列值尺寸 必须置 0 创建保存散列值的缓冲区 pBuffer new char dwBufferSize Get hash value bResult CryptGetHashParam hHash 散列对象句柄 HP HASHVAL 得到散列值 pBuffer 保存散列值长度缓冲区 必须置 0 释放散列对象 CryptDestroyHash hHash 上面例子为 pBuffer 指向的数据生成一个散列值 如果还要散列其它数据 用这个数据调用 CryptHashData 产生的散列值仍会是 原来的值 已警告过 使用 HP HASHVALUE 参数调用 CryptGetHashParam 会阻止使用此对象继续进行散列 生成密鈅 生成密鈅 CryptDeriveKey CryptDeriveKey CryptGenKey CryptGenKey CryptDestroyKeyCryptDestroyKey 这三个函数用来产生密鈅句柄 CryptDeriveKey 函数从一个指定的密码 password 产生密鈅 CryptGenKey 函数从一个随机产生的数值产生密鈅 CryptDestroyKey 函数释放密鈅对象 使用 CryptGenKey 函数时 建议使用 CRYPT EXPORTABLE 参数以创建一个可导出的会话密鈅 这会建立一个可从一台机器移到另一 台机器的值 不提供此参数 返回值仅在此机器 会话中有效 下面是如何使用 CryptDeriveKey 函数的例子 假定 pPassword 指向一个用户指定的密码 dwPasswordLength 为密码长度 include 对 CryptoAPI 的定义 对于非 C C 用户 此处用到的常量如下 define ALG CLASS HASH 4 13 define ALG TYPE ANY 0 define ALG SID MD5 3 define CALG MD5 ALG CLASS HASH ALG TYPE ANY ALG SID MD5 define CRYPT EXPORTABLE 0 x00000001 define ALG CLASS DATA ENCRYPT 3 13 define ALG TYPE STREAM 4 9 define ALG SID RC2 2 define CALG RC4 ALG CLASS DATA ENCRYPT ALG TYPE STREAM ALG SID RC4 BOOL bResult HCRYPTHASH hHash HCRYPTKEY hKey 获得散列对象句柄 bResult CryptCreateHash hProv 之前获得的 CSP 句柄 CALG MD5 散列算法 0 非密鈅散列 0 置 0 保存散列对象句柄的变量 散列数据 bResult CryptHashData hHash 散列对象句柄 pPassword 指向密码的指针 dwPasswordLength 数据长度 0 未指定值 从指定的密码产生密鈅 bResult CryptDeriveKey hProv 之前获得的 CSP 句柄 CALG RC4 流加密 hHash 密码散列后对象句柄 CRYPT EXPORTABLE 密鈅可导出 保存密鈅对象句柄的变量 用密鈅进行操作 释放散列对象 CryptDestroyHash hHash 释放密鈅对象 CryptDestroyKey hKey 加密与解密数据 加密与解密数据 CryptEncrypt CryptEncrypt CryptDecryptCryptDecrypt 简单来说 尽管不全对 加密 API 处理数据是围绕两个函数 加密 CryptEncrypt 与解密 CryptDecrypt 这两个函数非常易用 但需要对其参数进行一下说明 每个函数的头六个参数是相同的 头两个参数仅是密鈅句柄和一个可选的散列对象 第三个参数是一个布尔值 此值在最后一块数据块之前保持为 FALSE 为让函数对最后一块数据进行特殊处理 在最后一块数据时 置为 TRUE 第四与第五个参数是标志值和一个指向加密或解密数据的指针 第六个参数是缓冲区中待加密字符的数量 第七个参数通常与第六个参数相同 它指出数据块长度 这是因为对于许多算法来说 加密数据尺寸与解密数据尺寸是相同的 然 而 某些算法增加加密数据的长度 在这种情况下 第五个参数中的缓冲区必须大到足以容纳额外的数据 缓冲区长度的问题可以在加密前通过调用 CryptEncrypt 函数返回需要缓冲区的尺寸来解决 下面的例子代码演示了这种技术 在 这个例子中 某些值已假定之前已获得 我们仅要加密 pData 指向的缓冲区中 dwDataLen 字节长的数据 BOOL bResult PBYTE pBuffer DWORD dwSize 将缓冲中数据长度赋给变量 dwSize dwDataLen 让 API 返回给我们需要的缓冲长度 bResult CryptEncrypt hKey 之前获得的密鈅对象 0 不散列数据 TRUE 最后的还是缓冲的数据 0 必须置 0 NULL 无数据 简单的返回尺寸 数据块尺寸 现在得到了输出缓冲区尺寸 创建此缓冲区 pBuffer new char dwSize 加密数据 bResult CryptEncrypt hKey 之前获得的密鈅对象 0 不散列数据 TRUE 最后的还是缓冲的数据 0 必须置 0 pBuffer 数据缓冲区 数据块尺寸 同时进行加密与解密 当使用同一个密鈅进行加密或解密两个数据流时 必须采取一些措施 同一个物理会话密鈅不得被用于同一个操作 因为每个会话 密鈅容器的内部状态信息在同时进行一个操作时会混乱 对此问题的简单解决办法是制作一份会话密鈅的拷贝 这样 原始密鈅进行一 个操作 拷贝密鈅进行另一个操作 制作一个会话密鈅的拷贝可以通过调 CryptExportKey 导出密鈅 然后调 CryptImportKey 将它导进来 密鈅导入后 CSP 会给这 个 新 的密鈅分配自己的内部内存区域 就好象它跟原来的密鈅完全没有关联一样 CRYPTOAPICRYPTOAPI 例程例程 程序有下列命令行结构 Usage Encrypt switch arguments Where switch and optional arguments are one of Switch Arguments Description A DDUSER to add user to CSP table R EMOVEUSER to remove user from CSP table E NCRYPT uf ef pwd to encrypt a file D ECRYPT ef uf pwd to decrypt a file S IGN uf sf desc to sign a file V ERIFY uf sf desc to verify a signed file C SP to show CSP statistics and uf name of an unencrypted file ef name of an encrypted file sf name of a signed file pwd optional password desc optional signature description 编码问题编码问题 需要显式地在例程中定义特定的常量 因为加密 API 头文件 wincrypt h 使用 WIN32 WINNT 常量来检测正在使用哪个 Windows NT 版本 当写此例程时 此常量尽管需要 但当前的编译器仍然未定义它 定义此常量代码才不会编译出错 可以在以后的编译器定义 它后再将其移除 API 函数 CryptAcquireContext 有一个未文档化的常量值 MS DEF PROV 这个常量用来指代默认 CSP 这个值用在 ADDUSER 命令 行开关中 这允许程序使用任何已安装的 CSP 不需要知道其名字 增加或者删除一个用户 ADDUSER 与 REMOVERUSER 开关用来增加或删除一个默认的加密客户端 为使其它加密功能运行正常 ADDUSER 开关必须首先被 调用 下面一系列操作会被执行 一个默认密鈅容器被创建 一个数字签名密鈅对在密鈅容器中被创建 一个密鈅交换密鈅对在密鈅容器中被创建 这项操作仅需执行一次 除非操作系统重装 假如默认的密鈅容器与密鈅对已经创建 那么再次使用这个开关没有效果 从命令行运行 ADDUSER 开关如下 Encrypt ADDUSER 从命令行运行 REMOVEUSER 开关如下 Encrypt REMOVEUSER 加密或解密文件 ENCRYPT 开关用来加密文件 通过这个开关加密的文件以后可以通过 DECRYPT 开关解密 注意 为了给默认用户创建一个密鈅容器 必须在进行任何加密前调用 ADDUSER 开关 从命令行运行 ENCRYPT 开关如下 Encrypt encrypt 参数指定要加

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论