OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。 作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
对称加密算法
OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。事实上,DES算法里面不仅仅是常用的DES算法,还支持三个密钥和两个密钥3DES算法。
非对称加密算法
OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法一般用户密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。
信息摘要算法
OpenSSL实现了5种信息摘要算法,分别是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包括了SHA和SHA1两种信息摘要算法,此外,OpenSSL还实现了DSS标准中规定的两种信息摘要算法DSS和DSS1。 我们来用VC++实现文件加密,请见代码实现与注释讲解 [cpp] view plaincopy
- #include <stdio.h>
- #include <string.h>
- #include <conio.h>
- #include <windows.h>
- #include <wincrypt.h>
- #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
- #define KEYLENGTH 0x00800000
- void HandleError(char *s);
- HCRYPTPROV GetCryptProv();
-
- #define ENCRYPT_ALGORITHM CALG_RC4
- #define ENCRYPT_BLOCK_SIZE 8
-
-
- BOOL EncryptFile(
- PCHAR szSource,
- PCHAR szDestination,
- PCHAR szPassword);
-
- HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword);
- HCRYPTKEY GenKeyByRandom(HCRYPTPROV hCryptProv,FILE* hDestination);
-
- //-------------------------------------------------------------------
- // Begin main.
-
- void main(void)
- {
- PCHAR szSource;
- PCHAR szDestination;
- CHAR szPassword[100] = "";
- char response;
-
- if(!(szSource=(char *)malloc(100)))
- HandleError("Memory allocation failed.");
- if(!(szDestination=(char *)malloc(100)))
- HandleError("Memory allocation failed.");
-
- printf("加密一个文件. \n\n");
- printf("请输入需要被加密文件的名称: ");
- fgets(szSource, 100, stdin);
- if(szSource[strlen(szSource)-1] == '\n')
- szSource[strlen(szSource)-1] = '\0';
- printf("请输入需要输出文件文件的名称: ");
- fgets(szDestination, 100, stdin);
- if(szDestination[strlen(szDestination)-1] == '\n')
- szDestination[strlen(szDestination)-1] = '\0';
- printf("要使用密码对这个文件加密吗? ( y/n ) ");
- response = getchar();
- if(response == 'y')
- {
- printf("请输入密码:");
- getchar();
- gets(szPassword);
- }
- else
- {
- printf("密钥将生成但没有使用密码. \n");
- }
-
- //-------------------------------------------------------------------
- // 调用函数 EncryptFile 进行实际的加密操作.
-
- if(EncryptFile(szSource, szDestination, szPassword))
- {
- printf("对文件 %s 的加密已经成功! \n",
- szSource);
- printf("加密后的数据存储在文件 %s 中.\n",szDestination);
- }
- else
- {
- HandleError("解密文件出错!");
- }
- //-------------------------------------------------------------------
- // 释放内存.
- if(szSource)
- free(szSource);
- if(szDestination)
- free(szDestination);
-
- } // end main
-
- //-------------------------------------------------------------------
- // 功能:加密原文szSource文件,加密后的数据存储在szDestination文件中
- // 参数:
- // szSource:原文文件名
- // szDestination:加密后数据存储文件
- // szPassword:用户输入的密码
- static BOOL EncryptFile(
- PCHAR szSource,
- PCHAR szDestination,
- PCHAR szPassword)
- {
- //-------------------------------------------------------------------
- // 变量申明与初始化.
-
- FILE *hSource;
- FILE *hDestination;
-
- HCRYPTPROV hCryptProv;
- HCRYPTKEY hKey;
-
-
- PBYTE pbBuffer;
- DWORD dwBlockLen;
- DWORD dwBufferLen;
- DWORD dwCount;
-
- //-------------------------------------------------------------------
- // 打开原文文件.
- if(hSource = fopen(szSource,"rb"))
- {
- printf("原文文件 %s 已经打开. \n", szSource);
- }
- else
- {
- HandleError("打开原文文件出错!");
- }
-
- //-------------------------------------------------------------------
- // 打开目标文件.
- if(hDestination = fopen(szDestination,"wb"))
- {
- printf("目标文件 %s 已经打开. \n", szDestination);
- }
- else
- {
- HandleError("打开目标文件出错!");
- }
- //获取加密服务者句柄
- hCryptProv = GetCryptProv();
-
- //-------------------------------------------------------------------
- // 创建会话密钥.
- if(!szPassword || strcmp(szPassword,"")==0 )
- {
-
- //--------------------------------------------------------------
- // 当输入密码为空时,则创建随机的加密密钥,并导出创建的密钥保存到文件中.
-
- hKey = GenKeyByRandom( hCryptProv, hDestination);
-
-
- }
- else
- {
- //--------------------------------------------------------------
- // 当输入密码不为空时,则通过输入密码创建加密密钥
-
- hKey=GenKeyByPassword( hCryptProv, szPassword);
-
- }
-
- //--------------------------------------------------------------------
- // 因为加密算法按ENCRYPT_BLOCK_SIZE 大小块加密,所以被加密的
- // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的
- // 数据长度。
-
- dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
-
- //--------------------------------------------------------------------
- // 确定加密后密文数据块大小. 若是分组密码模式,则必须有容纳额外块的空间
-
- if(ENCRYPT_BLOCK_SIZE > 1)
- dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
- else
- dwBufferLen = dwBlockLen;
-
- //-------------------------------------------------------------------
- // 分配内存空间.
- if(pbBuffer = (BYTE *)malloc(dwBufferLen))
- {
- printf("已经为缓冲区分配了内存. \n");
- }
- else
- {
- HandleError("所需内存不够. \n");
- }
-
- //-------------------------------------------------------------------
- // 循环加密 原文件
- do
- {
-
- //-------------------------------------------------------------------
- // 每次从原文件中读取dwBlockLen字节数据.
- dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
- if(ferror(hSource))
- {
- HandleError("读取明文文件出错!\n");
- }
-
- //-------------------------------------------------------------------
- // 加密数据.
- if(!CryptEncrypt(
- hKey, //密钥
- 0, //如果数据同时进行散列和加密,这里传入一个散列对象
- feof(hSource), //如果是最后一个被加密的块,输入TRUE.如果不是输入FALSE.
- //这里通过判断是否到文件尾来决定是否为最后一块。
- 0, //保留
- pbBuffer, //输入被加密数据,输出加密后的数据
- &dwCount, //输入被加密数据实际长度,输出加密后数据长度
- dwBufferLen)) //pbBuffer的大小。
- {
- HandleError("Error during CryptEncrypt. \n");
- }
-
- //-------------------------------------------------------------------
- // 把加密后数据写到密文文件中
-
- fwrite(pbBuffer, 1, dwCount, hDestination);
- if(ferror(hDestination))
- {
- HandleError("写入密文时出错.");
- }
-
- } while(!feof(hSource));
-
- //-------------------------------------------------------------------
- // 关闭文件
-
- if(hSource)
- {
- if(fclose(hSource))
- HandleError("关闭原文文件出错!");
- }
- if(hDestination)
- {
- if(fclose(hDestination))
- HandleError("关闭目标文件出错!");
- }
-
- //-------------------------------------------------------------------
- // 释放内存空间.
-
- if(pbBuffer)
- free(pbBuffer);
-
- //-------------------------------------------------------------------
- // 销毁会话密钥
-
- if(hKey)
- {
- if(!(CryptDestroyKey(hKey)))
- HandleError("Error during CryptDestroyKey");
- }
-
- //-------------------------------------------------------------------
- // 释放CSP句柄
-
- if(hCryptProv)
- {
- if(!(CryptReleaseContext(hCryptProv, 0)))
- HandleError("Error during CryptReleaseContext");
- }
- return(TRUE);
- } // end Encryptfile
-
-
- //获取加密提供者句柄
- HCRYPTPROV GetCryptProv()
- {
- HCRYPTPROV hCryptProv; // 加密服务提供者句柄
-
- //获取加密提供者句柄
- if(CryptAcquireContext(
- &hCryptProv, // 加密服务提供者句柄
- NULL, // 密钥容器名,这里使用登陆用户名
- MS_ENHANCED_PROV, // 加密服务提供者
- PROV_RSA_FULL, // 加密服务提供者类型,可以提供加密和签名等功能
- 0)) // 标志
- {
- printf("加密服务提供者句柄获取成功!\n");
- }
- else
- {
-
-
- //重新建立一个新的密钥集
- if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
- {
- HandleError("重新建立一个新的密钥集出错!");
- }
-
- }
- return hCryptProv;
- }
-
-
- // HandleError:错误处理函数,打印错误信息,并退出程序
- void HandleError(char *s)
- {
- printf("程序执行发生错误!\n");
- printf("%s\n",s);
- printf("错误代码为: %x.\n",GetLastError());
- printf("程序终止执行!\n");
- exit(1);
- }
-
-
- // GenKeyByRandom:通过随机数创建会话密钥
- // 参数:hCryptProv CSP句柄
- // hDestination 目标文件,导出的会话密钥保存在此文件中
- HCRYPTKEY GenKeyByRandom(HCRYPTPROV hCryptProv,FILE* hDestination)
- {
- HCRYPTKEY hKey;
- HCRYPTKEY hXchgKey;
-
- PBYTE pbKeyBlob;
- DWORD dwKeyBlobLen;
-
- if(CryptGenKey(
- hCryptProv,
- ENCRYPT_ALGORITHM,
- KEYLENGTH | CRYPT_EXPORTABLE,
- &hKey))
- {
- printf("一个会话密钥已经被创建. \n");
- }
- else
- {
- HandleError("Error during CryptGenKey. \n");
- }
- //--------------------------------------------------------------
- // 创建交换密钥
- if(CryptGenKey(
- hCryptProv,
- AT_KEYEXCHANGE,
- 0,
- &hXchgKey))
- {
- printf("交换密钥对已经创建.\n");
- }
- else
- {
- HandleError("在试图创建交换密钥时出错.\n");
- }
-
- //--------------------------------------------------------------
- // 确定密钥数据块长度,并分配空间.
-
- if(CryptExportKey(
- hKey,
- hXchgKey,
- SIMPLEBLOB,
- 0,
- NULL,
- &dwKeyBlobLen))
- {
- printf("此密钥块的长度是 %d 字节. \n",dwKeyBlobLen);
- }
- else
- {
- HandleError("计算密钥数据块长度出错! \n");
- }
- if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
- {
- printf("已经问此密钥块分配了内存. \n");
- }
- else
- {
- HandleError("所需内存不够. \n");
- }
- //--------------------------------------------------------------
- // 导出会话密钥到简单密钥数据块中.
-
- if(CryptExportKey(
- hKey,
- hXchgKey,
- SIMPLEBLOB,
- 0,
- pbKeyBlob,
- &dwKeyBlobLen))
- {
- printf("此会话密钥已经被导出. \n");
- }
- else
- {
- HandleError("Error during CryptExportKey!\n");
- }
- //--------------------------------------------------------------
- //释放交换密钥句柄.
-
- if(hXchgKey)
- {
- if(!(CryptDestroyKey(hXchgKey)))
- HandleError("Error during CryptDestroyKey");
-
- hXchgKey = 0;
- }
-
- //--------------------------------------------------------------
- // 写密钥块长度到目标文件.
-
- fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
- if(ferror(hDestination))
- {
- HandleError("写密钥块长度出错.");
- }
- else
- {
- printf("密钥块长度已经被写入. \n");
- }
- //--------------------------------------------------------------
- //写密钥块数据到目标文件.
-
- fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
- if(ferror(hDestination))
- {
- HandleError("写密钥数据出错");
- }
- else
- {
- printf("此密钥块数据已经被写入目标文件. \n");
- }
- // 释放内存空间.
- free(pbKeyBlob);
- //返回创建的会话密钥
- return hKey;
- }
-
- // GenKeyByRandom:通过输入密码创建会话密钥
- // 参数:hCryptProv CSP句柄
- // szPassword 输入密码
- HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword)
- {
- HCRYPTKEY hKey;
- HCRYPTHASH hHash;
- //-------------------------------------------------------------------
- // 创建哈希句柄.
-
- if(CryptCreateHash(
- hCryptProv,
- CALG_MD5,
- 0,
- 0,
- &hHash))
- {
- printf("一个哈希句柄已经被创建. \n");
- }
- else
- {
- HandleError("Error during CryptCreateHash!\n");
- }
- //-------------------------------------------------------------------
- // 计算输入密码的哈希值.
-
- if(CryptHashData(
- hHash,
- (BYTE *)szPassword,
- strlen(szPassword),
- 0))
- {
- printf("密码已经被添加到了哈希表中. \n");
- }
- else
- {
- HandleError("Error during CryptHashData. \n");
- }
- //-------------------------------------------------------------------
- // 通过哈希值创建会话密钥.
-
- if(CryptDeriveKey(
- hCryptProv,
- ENCRYPT_ALGORITHM,
- hHash,
- KEYLENGTH,
- &hKey))
- {
- printf("通过密码的哈希值获得了加密密钥. \n");
- }
- else
- {
- HandleError("Error during CryptDeriveKey!\n");
- }
- //-------------------------------------------------------------------
- // 销毁哈希句柄.
-
- if(hHash)
- {
- if(!(CryptDestroyHash(hHash)))
- HandleError("Error during CryptDestroyHash");
- hHash = 0;
- }
-
- //返回创建的会话密钥
- return hKey;
- }
我们来用VC++实现文件解密,请见代码实现与注释讲解
[cpp] view plaincopy
- #include <stdio.h>
- #include <string.h>
- #include <conio.h>
- #include <windows.h>
- #include <wincrypt.h>
- #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
- #define KEYLENGTH 0x00800000
- void HandleError(char *s);
- HCRYPTPROV GetCryptProv();
-
- #define ENCRYPT_ALGORITHM CALG_RC4
- #define ENCRYPT_BLOCK_SIZE 8
-
- BOOL DecryptFile(
- PCHAR szSource,
- PCHAR szDestination,
- CHAR *szPassword);
-
- HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword);
- HCRYPTKEY GenKeyFromFile(HCRYPTPROV hCryptProv,FILE* hSource);
-
- void main(void)
- {
- //--------------------------------------------------------------------
- // 变量申明与初始化.
-
- PCHAR szSource;
- PCHAR szDestination;
- CHAR szPassword[100] = "";
- char response;
-
- if(!(szSource=(char *)malloc(100)))
- HandleError("Memory allocation failed.");
- if(!(szDestination=(char *)malloc(100)))
- HandleError("Memory allocation failed.");
-
- printf("解密一个文件. \n\n");
- printf("请输入需要解密文件的名称: ");
- fgets(szSource, 100, stdin);
- if(szSource[strlen(szSource)-1] == '\n')
- szSource[strlen(szSource)-1] = '\0';
- printf("请输入要输出文件的名称: ");
- fgets(szDestination, 100, stdin);
- if(szDestination[strlen(szDestination)-1] == '\n')
- szDestination[strlen(szDestination)-1] = '\0';
- printf("加密这个文件时是否使用了密码? ( y/n ) ");
- response = getchar();
- if(response == 'y')
- {
- getchar();
- printf("请输入密码:");
- gets(szPassword);
- }
- else
- {
- printf("密钥将被生成但没有使用密码. \n");
- }
- //解密文件
- if(!DecryptFile(szSource, szDestination, szPassword))
- {
- printf("\nError decrypting file. \n");
- }
- else
- {
- printf("\n对文件 %s 的解密成功了. \n", szSource);
- printf("被解密的文件是 %s .\n",szDestination);
- }
- //--------------------------------------------------------------------
- // 释放内存空间.
- if(szSource)
- free(szSource);
- if(szDestination)
- free(szDestination);
-
- } // End main
-
- //-------------------------------------------------------------------
- // 功能:解密密文szSource文件,解密后的数据存储在szDestination文件中
- // 参数:
- // szSource:密文文件名
- // szDestination:解密后数据存储文件
- // szPassword:用户输入的密码
-
- static BOOL DecryptFile(
- PCHAR szSource,
- PCHAR szDestination,
- PCHAR szPassword)
- {
- //--------------------------------------------------------------------
- // 局部变量申明与初始化.
-
- FILE *hSource;
- FILE *hDestination;
-
- HCRYPTPROV hCryptProv;
- HCRYPTKEY hKey;
-
- PBYTE pbBuffer;
- DWORD dwBlockLen;
- DWORD dwBufferLen;
- DWORD dwCount;
-
- BOOL status = FALSE;
-
- //--------------------------------------------------------------------
- // 打开密文文件.
- if(!(hSource = fopen(szSource,"rb")))
- {
- HandleError("打开密文文件出错!");
- }
- //--------------------------------------------------------------------
- // 打开目标文件,用于存储解密后的数据.
-
- if(!(hDestination = fopen(szDestination,"wb")))
- {
- HandleError("打开明文文件出错!");
- }
-
- //获取加密服务者句柄
- hCryptProv = GetCryptProv();
-
- //获取或创建会话密钥
- if(!szPassword|| strcmp(szPassword,"")==0 )
- {
- //--------------------------------------------------------------------
- //从密文文件导入保存的会话密钥
-
- hKey = GenKeyFromFile( hCryptProv,hSource);
-
- }
- else
- {
- //--------------------------------------------------------------------
- // 通过输入密码重新创建会话密钥.
-
- hKey=GenKeyByPassword( hCryptProv, szPassword);
- }
-
-
- // 计算一次解密的数据长度,它是ENCRYPT_BLOCK_SIZE 的整数倍
-
- dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
- dwBufferLen = dwBlockLen;
-
- //--------------------------------------------------------------------
- // 分配内存空间.
-
- if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
- {
- HandleError("所需内存不够!\n");
- }
- //--------------------------------------------------------------------
- // 解密密文文件,解密后数据保存在目标文件
-
- do {
- //--------------------------------------------------------------------
- // 每次从密文文件中读取dwBlockLen字节数据.
-
- dwCount = fread(
- pbBuffer,
- 1,
- dwBlockLen,
- hSource);
- if(ferror(hSource))
- {
- HandleError("读取密文文件出错!");
- }
- //--------------------------------------------------------------------
- // 解密 数据
- if(!CryptDecrypt(
- hKey,
- 0,
- feof(hSource),
- 0,
- pbBuffer,
- &dwCount))
- {
- HandleError("Error during CryptDecrypt!");
- }
- //--------------------------------------------------------------------
- // 把解密后的数据写入目标文件中.
-
- fwrite(
- pbBuffer,
- 1,
- dwCount,
- hDestination);
- if(ferror(hDestination))
- {
- HandleError("Error writing plaintext!");
- }
- } while(!feof(hSource));
-
- status = TRUE;
-
- //--------------------------------------------------------------------
- // 关闭文件
- if(hSource)
- {
- if(fclose(hSource))
- HandleError("关闭原文件出错");
- }
- if(hDestination)
- {
- if(fclose(hDestination))
- HandleError("关闭目标文件出错");
- }
-
- //--------------------------------------------------------------------
- // 释放内存空间
-
- if(pbBuffer)
- free(pbBuffer);
-
- //--------------------------------------------------------------------
- // 销毁会话密钥
-
- if(hKey)
- {
- if(!(CryptDestroyKey(hKey)))
- HandleError("Error during CryptDestroyKey");
- }
-
- //--------------------------------------------------------------------
- // 释放CSP句柄
- if(hCryptProv)
- {
- if(!(CryptReleaseContext(hCryptProv, 0)))
- HandleError("Error during CryptReleaseContext");
- }
-
- return status;
- } // end Decryptfile
-
-
- //获取加密提供者句柄
- HCRYPTPROV GetCryptProv()
- {
- HCRYPTPROV hCryptProv; // 加密服务提供者句柄
-
- //获取加密提供者句柄
- if(CryptAcquireContext(
- &hCryptProv, // 加密服务提供者句柄
- NULL, // 密钥容器名,这里使用登陆用户名
- MS_ENHANCED_PROV, // 加密服务提供者
- PROV_RSA_FULL, // 加密服务提供者类型,可以提供加密和签名等功能
- 0)) // 标志
- {
- printf("加密服务提供者句柄获取成功!\n");
- }
- else
- {
-
- //重新建立一个新的密钥集
- if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
- {
- HandleError("重新建立一个新的密钥集出错!");
- }
-
- }
- return hCryptProv;
- }
-
-
- // HandleError:错误处理函数,打印错误信息,并退出程序
- void HandleError(char *s)
- {
- printf("程序执行发生错误!\n");
- printf("%s\n",s);
- printf("错误代码为: %x.\n",GetLastError());
- printf("程序终止执行!\n");
- exit(1);
- }
-
- // GenKeyFromFile:从密文文件中导出会话密钥
- // 参数:hCryptProv CSP句柄
- // hSource 保存会话密钥的文件
- HCRYPTKEY GenKeyFromFile(HCRYPTPROV hCryptProv,FILE* hSource)
- {
- HCRYPTKEY hKey;
-
- PBYTE pbKeyBlob;
- DWORD dwKeyBlobLen;
-
- //从密文文件中获取密钥数据块长度,并分配内存空间.
- fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource);
- if(ferror(hSource) || feof(hSource))
- {
- HandleError("读取密文文件中密钥数据块长度出错!");
- }
- if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen)))
- {
- HandleError("内存分配出错.");
- }
- //--------------------------------------------------------------------
- // 从密文文件中获取密钥数据块
-
- fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);
- if(ferror(hSource) || feof(hSource))
- {
- HandleError("读取密文文件中密钥数据块出错!\n");
- }
- //--------------------------------------------------------------------
- // 导入会话密钥到 CSP.
- if(!CryptImportKey(
- hCryptProv,
- pbKeyBlob,
- dwKeyBlobLen,
- 0,
- 0,
- &hKey))
- {
- HandleError("Error during CryptImportKey!");
- }
-
- if(pbKeyBlob)
- free(pbKeyBlob);
-
- //返回导出的会话密钥
- return hKey;
- }
-
- // GenKeyByPassword:通过输入密码创建会话密钥
- // 参数:hCryptProv CSP句柄
- // szPassword 输入密码
- HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword)
- {
- HCRYPTKEY hKey;
- HCRYPTHASH hHash;
- //-------------------------------------------------------------------
- // 创建哈希句柄.
-
- if(CryptCreateHash(
- hCryptProv,
- CALG_MD5,
- 0,
- 0,
- &hHash))
- {
- printf("一个哈希句柄已经被创建. \n");
- }
- else
- {
- HandleError("Error during CryptCreateHash!\n");
- }
- //-------------------------------------------------------------------
- // 计算输入密码的哈希值.
-
- if(CryptHashData(
- hHash,
- (BYTE *)szPassword,
- strlen(szPassword),
- 0))
- {
- printf("此密码已经被添加到了哈希表中. \n");
- }
- else
- {
- HandleError("Error during CryptHashData. \n");
- }
- //-------------------------------------------------------------------
- // 通过哈希值创建会话密钥.
-
- if(CryptDeriveKey(
- hCryptProv,
- ENCRYPT_ALGORITHM,
- hHash,
- KEYLENGTH,
- &hKey))
- {
- printf("从这个密码的哈希值获得了一个加密密钥. \n");
- }
- else
- {
- HandleError("Error during CryptDeriveKey!\n");
- }
- //-------------------------------------------------------------------
- // 销毁哈希句柄.
-
- if(hHash)
- {
- if(!(CryptDestroyHash(hHash)))
- HandleError("Error during CryptDestroyHash");
- hHash = 0;
- }
-
- //返回创建的会话密钥
- return hKey;
- }
|