密码引擎加密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句柄等。

 

 

 

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

以上是 密码引擎加密API实现与测试20181308邵壮 [操作系统入门] 的全部内容, 来源链接: utcz.com/z/519629.html

回到顶部