zoukankan      html  css  js  c++  java
  • 使用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;

    }

  • 相关阅读:
    Sqlite判断字段存在
    JS实现返回上一页面并刷新(转)
    WebService上传文件到服务器(转)
    ASP.NET中的DES加密解密,可用于URL传参(转)
    my97日期控件网址
    window.open用法详解(转)
    repeater绑定后alter不能弹出的解决办法(转)
    SQL Server之其他函数——类型转换函数(convert用法)(转)
    asp.net 无刷新分页时无法弹出alert对话框的解决方法 (转)
    UVa
  • 原文地址:https://www.cnblogs.com/buffer/p/1408406.html
Copyright © 2011-2022 走看看