• 密码引擎-加密API实现与测试 20181308邵壮


    1、熟悉Windows CryptoAPI提供的常用函数接口。

    2、掌握Windows CryptoAPI的使用。

    3、利用Windows CryptoAPI设计和实现一个小型密码系统(如文件加密机),完成加解密、摘要运算、数字签名等功能。

    1. 先编写一个加密的代码,使用Windows crypticAPI实现。

    结果如图:

     

     

    2.编写一个解密的代码,使用Windows crypticAPI实现。

     

     

     

    3. 编写一个计算文件的代码,使用Windows crypticAPI实现文件的MD5计算。

    用写好的代码测试123.dll,启动代码结果:

     

    以下是代码共三个:分别是加密解密和计算MD5

     

     

    加密

    #include <stdio.h>

    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    #include <wincrypt.h>

    #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

    #define KEYLENGTH  0x00800000

    void HandleError(char *s);

    #define ENCRYPT_ALGORITHM CALG_RC4

    #define ENCRYPT_BLOCK_SIZE 8

    BOOL EncryptFile(

                                 PCHAR szSource,

                                 PCHAR szDestination,

                                 PCHAR szPassword);

    void main(void)

    {

        CHAR szSource[100];

        CHAR szDestination[100];

        CHAR szPassword[100];

          

          

           printf("Encrypt a file. ");

           printf("Enter the name of the file to be encrypted: ");

           scanf("%s",szSource);

           printf("Enter the name of the output file: ");

           scanf("%s",szDestination);

           printf("Enter the password:");

           scanf("%s",szPassword);

          

           if(EncryptFile(szSource, szDestination, szPassword))

           {

                  printf("Encryption of the file %s was a success. ", szSource);

                  printf("The encrypted data is in file %s. ",szDestination);

           }

           else

           {

                  HandleError("Error encrypting file!");

           }

    }

    static BOOL EncryptFile(

                                              PCHAR szSource,

                                              PCHAR szDestination,

                                              PCHAR szPassword)

                                              //--------------------------------------------------------------------

                                              //   Parameters passed are:

                                              //     szSource, the name of the input, a plaintext file.

                                              //     szDestination, the name of the output, an encrypted file to be

                                              //         created.

                                              //     szPassword, the password.

    {

           FILE *hSource;

           FILE *hDestination;

          

           HCRYPTPROV hCryptProv;

           HCRYPTKEY hKey;

           HCRYPTHASH hHash;

                 

           PBYTE pbBuffer;

           DWORD dwBlockLen;

           DWORD dwBufferLen;

           DWORD dwCount;

           if(hSource = fopen(szSource,"rb"))

           {

                  printf("The source plaintext file, %s, is open. ", szSource);

           }

           else

           {

                  HandleError("Error opening source plaintext file!");

           }

           if(hDestination = fopen(szDestination,"wb"))

           {

                  printf("Destination file %s is open. ", szDestination);

           }

           else

           {

                  HandleError("Error opening destination ciphertext file!");

           }

           if(CryptAcquireContext(

                  &hCryptProv,

                  NULL,

                  NULL,

                  PROV_RSA_FULL,

                  0))

           {

                  printf("A cryptographic provider has been acquired. ");

           }

           else

           {

                  if(CryptAcquireContext(

                         &hCryptProv,

                         NULL,

                         NULL,

                         PROV_RSA_FULL,

                         CRYPT_NEWKEYSET))//创建密钥容器

                  {

                         //创建密钥容器成功,并得到CSP句柄

                         printf("A new key container has been created. ");

                  }

                  else

                  {

                         HandleError("Could not create a new key container. ");

                  }

                 

           }

           if(CryptCreateHash(

                  hCryptProv,

                  CALG_MD5,

                  0,

                  0,

                  &hHash))

        {

            printf("A hash object has been created. ");

        }

        else

        {

                  HandleError("Error during CryptCreateHash! ");

        } 

           if(CryptHashData(

                  hHash,

                  (BYTE *)szPassword,

                  strlen(szPassword),

                  0))

           {

                  printf("The password has been added to the hash. ");

           }

           else

           {

                  HandleError("Error during CryptHashData. ");

           }

           if(CryptDeriveKey(

                  hCryptProv,

                  ENCRYPT_ALGORITHM,

                  hHash,

                  KEYLENGTH,

                  &hKey))

           {

                  printf("An encryption key is derived from the password hash. ");

           }

           else

           {

                  HandleError("Error during CryptDeriveKey! ");

           }

           CryptDestroyHash(hHash);

           hHash = NULL;

          

           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("Memory has been allocated for the buffer. ");

           }

           else

           {

                  HandleError("Out of memory. ");

           }

           do

           {

                  dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);

                  if(ferror(hSource))

                  {

                         HandleError("Error reading plaintext! ");

                  }

                  if(!CryptEncrypt(

                         hKey,           

                         0,          

                         feof(hSource),

                         0,                         //保留

                         pbBuffer,       //输入被加密数据,输出加密后的数据

                         &dwCount,           //输入被加密数据实际长度,输出加密后数据长度

                         dwBufferLen))      //pbBuffer的大小。

                  {

                         HandleError("Error during CryptEncrypt. ");

                  }

                 

                  fwrite(pbBuffer, 1, dwCount, hDestination);

                  if(ferror(hDestination))

                  {

                         HandleError("Error writing ciphertext.");

                  }

                 

           }

           while(!feof(hSource));

          

           if(hSource)

                  fclose(hSource);

           if(hDestination)

                  fclose(hDestination);

           if(pbBuffer)

                  free(pbBuffer);

          

           if(hKey)

                  CryptDestroyKey(hKey);

          

           if(hHash)

                  CryptDestroyHash(hHash);

          

           if(hCryptProv)

                  CryptReleaseContext(hCryptProv, 0);

           return(TRUE);

    }

    void HandleError(char *s)

    {

        fprintf(stderr,"An error occurred in running the program. ");

        fprintf(stderr,"%s ",s);

        fprintf(stderr, "Error number %x. ", GetLastError());

        fprintf(stderr, "Program terminating. ");

        exit(1);

    }

    解密

    #include <stdio.h>

    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    #include <wincrypt.h>

    #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

    #define KEYLENGTH  0x00800000

    void HandleError(char *s);

    //--------------------------------------------------------------------

    #define ENCRYPT_ALGORITHM CALG_RC4

    #define ENCRYPT_BLOCK_SIZE 8

    BOOL DecryptFile(

                                 PCHAR szSource,

                                 PCHAR szDestination,

                                 PCHAR szPassword);

    void main(void)

    {    

           CHAR szSource[100];

           CHAR szDestination[100];

           CHAR szPassword[100];

          

           printf("Decrypt a file. ");

           printf("Enter the name of the file to be decrypted: ");

           scanf("%s",szSource);

           printf("Enter the name of the output file: ");

           scanf("%s",szDestination);

           printf("Enter the password:");

           scanf("%s",szPassword);

          

           if(!DecryptFile(szSource, szDestination, szPassword))

           {

                  printf(" Error decrypting file. ");

           }

           else

           {

                  printf(" Decryption of file %s succeeded. ", szSource);

                  printf("The decrypted file is %s . ",szDestination);

           }

    }

    static BOOL DecryptFile(

                                              PCHAR szSource,

                                              PCHAR szDestination,

                                              PCHAR szPassword)

    {

          

           FILE *hSource;

           FILE *hDestination;

          

           HCRYPTPROV hCryptProv;

           HCRYPTKEY hKey;

           HCRYPTHASH hHash;

          

           PBYTE pbBuffer;

           DWORD dwBlockLen;

           DWORD dwBufferLen;

           DWORD dwCount;

          

           BOOL status = FALSE;

           if(!(hSource = fopen(szSource,"rb")))

           {

                  HandleError("Error opening ciphertext file!");

           }

          

           if(!(hDestination = fopen(szDestination,"wb")))

           {

                  HandleError("Error opening plaintext file!");

           }

           if(!CryptAcquireContext(

                  &hCryptProv,

                  NULL,

                  NULL,

                  PROV_RSA_FULL,

                  0))

           {

                  HandleError("Error during CryptAcquireContext!");

           }

          

           if(!CryptCreateHash(

                  hCryptProv,

                  CALG_MD5,

                  0,

                  0,

                  &hHash))

           {

                  HandleError("Error during CryptCreateHash!");

           }

          

           if(!CryptHashData(

                  hHash,

                  (BYTE *)szPassword,

                  strlen(szPassword),

                  0))

           {

                  HandleError("Error during CryptHashData!");

           }

          

           if(!CryptDeriveKey(

                  hCryptProv,

                  ENCRYPT_ALGORITHM,

                  hHash,

                  KEYLENGTH,

                  &hKey))

           {

                  HandleError("Error during CryptDeriveKey!");

           }

          

           CryptDestroyHash(hHash);

           hHash = 0;

          

           dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;

           dwBufferLen = dwBlockLen;

          

           if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))

           {

                  HandleError("Out of memory! ");

           }

          

           do {

                 

                  dwCount = fread(

                         pbBuffer,

                         1,

                         dwBlockLen,

                         hSource);

                  if(ferror(hSource))

                  {

                         HandleError("Error reading ciphertext!");

                  }

                  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)

                  fclose(hSource);

           if(hDestination)

                  fclose(hDestination);

          

           if(pbBuffer)

                  free(pbBuffer);

          

           if(hKey)

                  CryptDestroyKey(hKey);

          

           if(hHash)

                  CryptDestroyHash(hHash);

          

          

           if(hCryptProv)

                  CryptReleaseContext(hCryptProv, 0);

          

           return status;

    }

    void HandleError(char *s)

    {

        fprintf(stderr,"An error occurred in running the program. ");

        fprintf(stderr,"%s ",s);

        fprintf(stderr, "Error number %x. ", GetLastError());

        fprintf(stderr, "Program terminating. ");

        exit(1);

    } // End of HandleError

    MD5

    #include <stdio.h>

    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    #include <wincrypt.h>

    #define CHECK_NULL_RET(bCondition) if (!bCondition) goto Exit0

    #define BUFSIZE 1024

    #define MD5LEN  16

    BOOL GetContentMD5(

        BYTE *pszFilePath,

        BOOL bFile,

        BOOL bUpperCase,

        TCHAR *pszResult,

        DWORD &dwStatus)

    {

        BOOL bResult = FALSE;

        HCRYPTPROV hProv = 0;

        HCRYPTHASH hHash = 0;

        HANDLE hFile = NULL;

        BYTE rgbFile[BUFSIZE];

        DWORD cbRead = 0;

        BYTE rgbHash[MD5LEN];

        DWORD cbHash = 0;

        CHAR rgbDigitsL[] = "0123456789abcdef";

        CHAR rgbDigitsU[] = "0123456789ABCDEF";

        CHAR *rgbDigits = bUpperCase ? rgbDigitsU : rgbDigitsL;

        TCHAR szResult[MD5LEN*2+1] = {0};

        dwStatus = 0;

        bResult = CryptAcquireContext(&hProv,

            NULL,

            NULL,

            PROV_RSA_FULL,

            CRYPT_VERIFYCONTEXT);

        CHECK_NULL_RET(bResult);

        bResult = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);

        CHECK_NULL_RET(bResult);

        if (bFile)

        {

            hFile = CreateFile((TCHAR *)pszFilePath,

                GENERIC_READ,

                FILE_SHARE_READ,

                NULL,

                OPEN_EXISTING,

                FILE_FLAG_SEQUENTIAL_SCAN,

                NULL);

            CHECK_NULL_RET(!(INVALID_HANDLE_VALUE == hFile));

            while (bResult = ReadFile(hFile, rgbFile, BUFSIZE,

                &cbRead, NULL))

            {

                if (0 == cbRead)

                {

                    break;

                }

                bResult = CryptHashData(hHash, rgbFile, cbRead, 0);

                CHECK_NULL_RET(bResult);

            }

        }

        else

        {

            bResult = CryptHashData(hHash, pszFilePath, strlen((CHAR *)pszFilePath), 0);

            CHECK_NULL_RET(bResult);

        }

        cbHash = MD5LEN;

        if (bResult = CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))

        {

            TCHAR szTmpBuff[3] ;

            for (DWORD i = 0; i < cbHash; i++)

            {

                sprintf  (szTmpBuff, TEXT("%c%c"), rgbDigits[rgbHash[i]>>4],

                    rgbDigits[rgbHash[i] & 0xf]);

                lstrcat(szResult, szTmpBuff);

            }

            bResult = TRUE;

        }

    Exit0:

        dwStatus = GetLastError();

        CryptDestroyHash(hHash);

        CryptReleaseContext(hProv, 0);

        CloseHandle(hFile);

        lstrcpy(pszResult, szResult);

        return bResult;

    }

    int main(int argc, char* argv[])

    {

        DWORD dwStatus = 0;

        TCHAR szResult[MD5LEN*2+1] = {0};

        TCHAR szFilePath[] = TEXT("C:\123.dll");

        CHAR szContent[] = "explorer.exe";

        GetContentMD5((BYTE *)szFilePath,

            TRUE, TRUE, szResult, dwStatus);

        MessageBox(NULL, szResult, TEXT("该文件的MD5"), MB_OK);

        return 0;

    }

     

    这次实验难度很大,过程中遇到了很多的问题。感觉从一开始就无从下手,所以只能先去上网找资料和相关博客等学习。在看了很多的资料和相关解答之后虽然还是一头雾水,但是还算是有了不少的了解。在找到了相关代码之后,自己做了一些修改,也算是完成了这次的任务。也算是对Windows CryptoAPI有了一个初步的了解了。

     

    利用Windows CryptoAPI进行加解密的一般步骤是怎样的?

     

    CryptoAPI使用两种密钥:会话密钥与公共/私人密钥对。会话密钥使用相同的加密和解密密钥,这种算法较快,但必须保证密钥的安全传递。公共/私人密钥对使用一个公共密钥和一个私人密钥,私人密钥只有专人才能使用,公共密钥可以广泛传播。如果密钥对中的一个用于加密,另一个一定用于解密。公共/私人密钥对算法很慢,一般只用于加密小批数据,例如用于加密会话密钥。

      CryptoAPI支持两种基本的编码方法:流式编码和块编码。流式编码在明码文本的每一位上创建编码位,速度较快,但安全性较低。块编码在一个完整的块上(一般为64位)上工作,需要使用填充的方法对要编码的数据进行舍入,以组成多个完整的块。这种算法速度较慢,但更安全。

     

     

     

     

    加密:

    1、打开源文件

    2、取得密钥容器(CSP)句柄

    3、根据用户输入的密码创建一个会话密钥(即对称密钥,用于对原文件加密)

    4、加密数据文件

    5、清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。

    解密:

    1、打开源文件

    2、取得密钥容器(CSP)句柄

    3、根据用户输入的密码创建一个会话密钥(即对称密钥,用于对原文件解密,

    这里要求用户输入的密码与加密时输入的密码相同。在实际应用中,这个所谓用户输入的“密码”其实只是一个产生密钥的种子,一旦产生完会话密钥,则用户完全 可以忘记当初输入的“密码”,接收方可以使用传过来的密钥直接对加密文件进行解密,而不用再重复一次“生成密钥”的过程。)

    4、解密数据文件

    5、清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。

     

     

     

  • 相关阅读:
    读书笔记
    STL 笔记
    Centos8如何配置网桥
    命令集合
    shared_ptr给管理的对象定制析沟函数
    share_ptr指向的对象的析构动作在创建的时候被捕获
    优秀博客
    字符串单词翻转
    带权图的最短路径算法(Dijkstra,Floyd,Bellman_ford)
    生产者与消费者 c++实现
  • 原文地址:https://www.cnblogs.com/King-King/p/14701748.html
Copyright © 2020-2023  润新知