使用WinCrypt进行简单的对称加密实例

微软在wincrypt.h中定义了大量的加解密算法的API,方便了软件加解密的实现,可以使我们不必关注密码学的算法,就可以实现高效率的软件加密。下面通过一个类,对API实现简单的封装。详细代码如下:

 

头文件:MyCryptOpt.h

#pragma once

 

#include "windows.h"

#include "wincrypt.h"

 

#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

#define KEYLENGTH 0x00800000

 

#define ENCRYPT_ALGORITHM CALG_RC4

#define ENCRYPT_BLOCK_SIZE 8

 

class CMyCryptOpt

{

public:

     CMyCryptOpt(void);

     ~CMyCryptOpt(void);

 

     BOOL InitCrypt();

     void DestroyCrypt();

 

     BOOL MyEncryptFile(LPSTR lpSourceFile, LPSTR lpDestFile, LPSTR lpPassword);

     BOOL MyDecryptFile(LPSTR lpSourceFile, LPSTR lpDestFile, LPSTR lpPassword);

 

protected:

     BOOL CryptProcess(LPSTR lpSourceFile, LPSTR lpDestFile, LPSTR lpPassword);

 

private:

     FILE *m_hSource;

     FILE *m_hDestination;

 

     HCRYPTPROV m_hCryptProv;

     HCRYPTKEY  m_hKey;

     HCRYPTHASH m_hHash;

 

     PBYTE m_pbBuffer;

     DWORD m_dwBlockLen;

     DWORD m_dwBufferLen;

     DWORD m_dwCount;

};


源文件:MyCryptOpt.cpp

#include "StdAfx.h"

#include "MyCryptOpt.h"

 

CMyCryptOpt::CMyCryptOpt(void)

{

}

 

CMyCryptOpt::~CMyCryptOpt(void)

{

}

 

BOOL CMyCryptOpt::InitCrypt()

{

     // 获得一个CSP句柄

     if (!CryptAcquireContext(&m_hCryptProv,NULL,NULL,PROV_RSA_FULL,0))

     {

         if (!CryptAcquireContext(

              &m_hCryptProv,

              NULL,

              NULL,

              PROV_RSA_FULL,

              CRYPT_NEWKEYSET))

         {

              OutputDebugString("CryptAcquireContext() error!");

              return FALSE;

         }

     }

 

     // 创建一个会话密钥

     if (!CryptCreateHash(

         m_hCryptProv,

         CALG_MD5,

         0,

         0,

         &m_hHash))

     {

         OutputDebugString("CryptCreateHash() error!");

         return FALSE;

     }

 

     return TRUE;

}

 

void CMyCryptOpt::DestroyCrypt()

{

     // close files

     if (m_hSource)

         fclose(m_hSource);

     if (m_hDestination)

         fclose(m_hDestination);

 

     // free memory

     if (m_pbBuffer)

         free(m_pbBuffer);

 

     // destroy session key

     if (m_hKey)

         CryptDestroyKey(m_hKey);

 

     // destroy hash object

     CryptDestroyHash(m_hHash);

     m_hHash = NULL;

 

     // Release provider handle

     if (m_hCryptProv)

         CryptReleaseContext(m_hCryptProv,0);

}

 

BOOL CMyCryptOpt::MyEncryptFile(LPSTR lpSourceFile, LPSTR lpDestFile, LPSTR lpPassword)

{

     // process for encrypt

     if (!CryptProcess(lpSourceFile,lpDestFile,lpPassword))

         return FALSE;

 

     // 加密源文件,并将加密后数据写入目标文件

     do

     {

         // read source file

         m_dwCount = fread(m_pbBuffer,1,m_dwBlockLen,m_hSource);

         if (ferror(m_hSource))

         {

              OutputDebugString("读写源文件错误!");

              return FALSE;

         }

 

         // encrypt data

         if (!CryptEncrypt(

              m_hKey,

              0,

              feof(m_hSource),

              0,

              m_pbBuffer,

              &m_dwCount,

              m_dwBufferLen))

         {

              OutputDebugString("CryptEncrypt() failed!");

              return FALSE;

         }

 

         // write data to file

         fwrite(m_pbBuffer,1,m_dwCount,m_hDestination);

         if (ferror(m_hDestination))

         {

              OutputDebugString("write file error!");

              return FALSE;

         }

     }

     while (!feof(m_hSource));

 

     return TRUE;

}

 

BOOL CMyCryptOpt::MyDecryptFile(LPSTR lpSourceFile, LPSTR lpDestFile, LPSTR lpPassword)

{

     // process for decrypt

     if (!CryptProcess(lpSourceFile,lpDestFile,lpPassword))

         return FALSE;

 

     // 解密源文件,并将解密后数据写入目标文件

     do

     {

         // read source file

         m_dwCount = fread(m_pbBuffer,1,m_dwBlockLen,m_hSource);

         if (ferror(m_hSource))

         {

              OutputDebugString("读写源文件错误!");

              return FALSE;

         }

 

         // decrypt data

         if (!CryptDecrypt(

              m_hKey,

              0,

              feof(m_hSource),

              0,

              m_pbBuffer,

              &m_dwCount))

         {

              OutputDebugString("CryptEncrypt() failed!");

              return FALSE;

         }

 

         // write data to file

         fwrite(m_pbBuffer,1,m_dwCount,m_hDestination);

         if (ferror(m_hDestination))

         {

              OutputDebugString("write file error!");

              return FALSE;

         }

     }

     while (!feof(m_hSource));

 

     return TRUE;

}

 

BOOL CMyCryptOpt::CryptProcess(LPSTR lpSourceFile, LPSTR lpDestFile, LPSTR lpPassword)

{

     // 打开要加密的源文件

     m_hSource = fopen(lpSourceFile,"rb");

     if (!m_hSource)

     {

         OutputDebugString("open source file failed!");

         return FALSE;

     }

 

     // 打开加密后产生的目标文件

     m_hDestination = fopen(lpDestFile,"wb");

     if (!m_hDestination)

     {

         OutputDebugString("open destination file failed!");

         return FALSE;

     }

 

     // 用输入的密码产生一个散列

     if (!CryptHashData(

         m_hHash,

         (BYTE*)lpPassword,

         strlen(lpPassword),

         0))

     {

         OutputDebugString("CryptHashData() failed!");

         return FALSE;

     }

 

     // 通过散列生成会话密钥

     if (!CryptDeriveKey(

         m_hCryptProv,

         ENCRYPT_ALGORITHM,

         m_hHash,

         KEYLENGTH,

         &m_hKey))

     {

         OutputDebugString("CryptDeriveKey() failed!");

         return FALSE;

     }

 

     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的,所以被加密的

     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的

     // 数据长度。

 

     m_dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;

 

     // Determine the block size. If a block cipher is used, 

     // it must have room for an extra block.

 

     if (ENCRYPT_BLOCK_SIZE > 1)

     {

         m_dwBufferLen = m_dwBlockLen + ENCRYPT_BLOCK_SIZE;

     }

     else

     {

         m_dwBufferLen = m_dwBlockLen;

     }

 

     // 为缓冲区分配内存

     m_pbBuffer = (BYTE*)malloc(m_dwBufferLen);

     if (!m_pbBuffer)

     {

         OutputDebugString("分配内存错误!");

         return FALSE;

     }

 

     return TRUE;

}


你可能感兴趣的:(使用WinCrypt进行简单的对称加密实例)