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

2021-05-15 17:27

阅读:471

标签:算法   摘要   xpl   code   数据文件   window   代码   etc   explore   

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

2、掌握Windows CryptoAPI的使用。

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

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

结果如图:

 

 技术图片

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

 

 技术图片

 

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

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

 技术图片

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

 

 

加密

#include

#define _WIN32_WINNT 0x0400
#include 
#include 

#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. \n\n");

       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. \n", szSource);

              printf("The encrypted data is in file %s.\n",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. \n", szSource);

       }

       else

       {

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

       }

 

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

       {

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

       }

       else

       {

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

       }

       if(CryptAcquireContext(

              &hCryptProv,

              NULL,

              NULL,

              PROV_RSA_FULL,

              0))

       {

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

       }

       else

       {

              if(CryptAcquireContext(

                     &hCryptProv,

                     NULL,

                     NULL,

                     PROV_RSA_FULL,

                     CRYPT_NEWKEYSET))//创建密钥容器

              {

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

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

              }

              else

              {

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

              }

             

       }

       if(CryptCreateHash(

              hCryptProv,

              CALG_MD5,

              0,

              0,

              &hHash))

    {

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

    }

    else

    {

              HandleError("Error during CryptCreateHash!\n");

    } 

       if(CryptHashData(

              hHash,

              (BYTE *)szPassword,

              strlen(szPassword),

              0))

       {

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

       }

       else

       {

              HandleError("Error during CryptHashData. \n");

       }

       if(CryptDeriveKey(

              hCryptProv,

              ENCRYPT_ALGORITHM,

              hHash,

              KEYLENGTH,

              &hKey))

       {

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

       }

       else

       {

              HandleError("Error during CryptDeriveKey!\n");

       }

       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. \n");

       }

       else

       {

              HandleError("Out of memory. \n");

       }

       do

       {

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

              if(ferror(hSource))

              {

                     HandleError("Error reading plaintext!\n");

              }

              if(!CryptEncrypt(

                     hKey,           

                     0,          

                     feof(hSource),

                     0,                         //保留

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

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

                     dwBufferLen))      //pbBuffer的大小。

              {

                     HandleError("Error during CryptEncrypt. \n");

              }

             

              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. \n");

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

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

    fprintf(stderr, "Program terminating. \n");

    exit(1);

}

 

 

 

解密

 

 

 

#include

#define _WIN32_WINNT 0x0400
#include 
#include 

#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. \n\n");

       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("\nError decrypting file. \n");

       }

       else

       {

              printf("\nDecryption of file %s succeeded. \n", szSource);

              printf("The decrypted file is %s .\n",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!\n");

       }

      

       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. \n");

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

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

    fprintf(stderr, "Program terminating. \n");

    exit(1);

} // End of HandleError

 

MD5

#include

#define _WIN32_WINNT 0x0400
#include 
#include 

#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

        {

            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句柄等。

 

 

 

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

标签:算法   摘要   xpl   code   数据文件   window   代码   etc   explore   

原文地址:https://www.cnblogs.com/King-King/p/14701748.html


评论


亲,登录后才可以留言!