⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inituser.c

📁 C++编程实践与技巧一书各章节的源码
💻 C
字号:
//encryptfile.c 文件加密演示程序

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);
//--------------------------------------------------------------------
//加密算法和分组长度标识
#define ENCRYPT_ALGORITHM CALG_RC2 
#define ENCRYPT_BLOCK_SIZE 8 

//加密函数声明
static BOOL CryptEncryptFile(
        PCHAR szSource, //明文文件名
        PCHAR szDestination, //密文文件名
        PCHAR szPassword//口令
		);
 
//--------------------------------------------------------------------
void main(void) 
{ 
    PCHAR szSource; 
    PCHAR szDestination; 
    PCHAR szPassword; 
    int  response;
 //为明文文件名分配空间
if(!(szSource=(char *)malloc(100)))
    HandleError("内存溢出");
//为密文文件名分配空间
if(!(szDestination=(char *)malloc(100)))
    HandleError("内存溢出");
//为口令字分配空间
if(!(szPassword=(char *)malloc(100)))
    HandleError("内存溢出");

printf("文件加密演示程序\n\n");
printf("请输入需要加密的文件名: ");
scanf("%s",szSource);
printf("请输入输出(密文)文件名: ");
scanf("%s",szDestination);
printf("加密文件是否需要口令? ( y/n ) ");
response=_getche();
if(response == 'y')
{
    printf("请输入口令:");
    scanf("%s",szPassword);
}
else
{
    printf("密钥的产生不需要口令\n");
    free(szPassword);
    szPassword = NULL;
}

//--------------------------------------------------------------------
//调用CryptEncryptFile函数完成实际加密操作
 
if(CryptEncryptFile(szSource, szDestination, szPassword))
{
       printf("加密文件%s成功\n", szSource);
       printf("加密好的数据在文件%s中\n",szDestination);
}
else
{
      HandleError("加密文件错误!"); 
} 
} // End of main
 
//--------------------------------------------------------------------
// 加密函数代码

BOOL CryptEncryptFile(
        PCHAR szSource, 
        PCHAR szDestination, 
        PCHAR szPassword)
//--------------------------------------------------------------------
//函数参数包括:
//     szSource:输入的明文文件名。
//     szDestination:输出的加密好的文件名。
//     szPassword:口令字符串,或者为空。
{ 
//--------------------------------------------------------------------
// 声明和初始化本地变量

FILE *hSource; 
FILE *hDestination; 

HCRYPTPROV hCryptProv; 
HCRYPTKEY hKey; 
HCRYPTKEY hXchgKey; 
HCRYPTHASH hHash; 

PBYTE pbKeyBlob; 
DWORD dwKeyBlobLen; 

PBYTE pbBuffer; 
DWORD dwBlockLen; 
DWORD dwBufferLen; 
DWORD dwCount; 
 
//--------------------------------------------------------------------
//打开需要加密的明文文件

if(hSource = fopen(szSource,"rb"))
{
   printf("明文文件, %s, 被打开\n", szSource);
}
else
{ 
   HandleError("打开明文文件出错!");
} 
//--------------------------------------------------------------------
// 打开存放密文的文件

if(hDestination = fopen(szDestination,"wb"))
{
     printf("密文文件,%s,被打开\n", szDestination);
}
else
{
    HandleError("打开密文文件的时候出错!"); 
}
//获取默认CSP句柄
if(CryptAcquireContext(
      &hCryptProv, 
      NULL, 
      NULL, 
      PROV_RSA_FULL, 
      0))
{
   printf("已经获得CSP句柄\n");
}
else
{
   HandleError("调用CryptAcquireContext函数时出错!"); 
}
//--------------------------------------------------------------------
//创建会话密钥

if(!szPassword ) 
{ 
     
     //如果没有口令,则使用一个随机会话密钥加密文件,并把密钥写到文件中。
     
     //---------------------------------------------------------------
     //创建随机会话密钥

     if(CryptGenKey(
          hCryptProv, 
          ENCRYPT_ALGORITHM, 
          CRYPT_EXPORTABLE, 
          &hKey))
      {
          printf("已经产生会话密钥\n");
      } 
      else
      {
          HandleError("调用CryptGenKey函数时出错\n"); 
      }
     //--------------------------------------------------------------- 
     //取得加密这交换公钥句柄 

     if(CryptGetUserKey(
           hCryptProv, 
           AT_KEYEXCHANGE, 
           &hXchgKey))
      {
            printf("用户公钥已获取\n");
       }
       else
       { 
             HandleError("用户公钥不存在"); 
       }
     //---------------------------------------------------------------
     //判断密钥块大小,并为其分配内存。 

     if(CryptExportKey(
           hKey, 
           hXchgKey, 
           SIMPLEBLOB, 
           0, 
           NULL, 
           &dwKeyBlobLen))
      {
           printf("密钥块为%d个字节长\n",dwKeyBlobLen);
       }
       else
       {  
            HandleError("计算密钥块长度时出错! \n");
       }
       if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
       { 
          printf("已经为密钥块分配内存\n");
       }
       else
       { 
          HandleError("内存溢出!\n"); 
       }
     //---------------------------------------------------------------
     //加密并把会话密钥输出到简单密钥块中。 
     
     if(CryptExportKey(
          hKey, 
          hXchgKey, 
          SIMPLEBLOB, 
          0, 
          pbKeyBlob, 
          &dwKeyBlobLen))
       {
           printf("密钥块已输出\n");
       } 
       else
       {
           HandleError("调用CryptExportKey函数时出错!\n");
       } 
     //---------------------------------------------------------------
     //释放密钥交换密钥句柄 
     CryptDestroyKey(hXchgKey); 
     hXchgKey = 0; 
 
     //---------------------------------------------------------------
     //把密钥块大小写进加密好的文件 

     fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); 
     if(ferror(hDestination))
     { 
         HandleError("写密文文件头时出错");
     }
     else
     {
         printf("文件头已写好\n");
     }
     //--------------------------------------------------------------
     //把密钥块写到密文文件中。 
     
     fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination); 
     if(ferror(hDestination))
     { 
        HandleError("写密文文件头出错");
     }
     else
     {
        printf("密钥块已被写到密文文件中\n");
     }
} 
else 
{ 
//--------------------------------------------------------------------
//文件将使用从口令得到的会话密钥进行加密。
// 当文件解密时将根据同样的口令产生同样的会话密钥来解密。

//--------------------------------------------------------------------
//创建哈希对象

if(CryptCreateHash(
       hCryptProv, 
       CALG_MD5, 
       0, 
       0, 
       &hHash))
    {
        printf("哈希对象已创建\n");
    }
    else
    { 
         HandleError("调用CryptCreateHash函数时出错!\n");
    }  
//--------------------------------------------------------------------
//对口令进行哈希

if(CryptHashData(
       hHash, 
       (BYTE *)szPassword, 
       strlen(szPassword), 
       0))
 {
    printf("口令已增加到哈希对象中\n");
 }
 else
 {
    HandleError("调用CryptHashData函数时出错\n"); 
 }
//--------------------------------------------------------------------
//从哈希对象获取会话密钥

if(CryptDeriveKey(
       hCryptProv, 
       ENCRYPT_ALGORITHM, 
       hHash, 
       0, 
       &hKey))
 {
   printf("加密密钥已经从口令哈希对象中获取\n"); 
 }
 else
 {
   HandleError("调用CryptDeriveKey函数时出错!\n"); 
 }
//--------------------------------------------------------------------
//销毁哈希对象

CryptDestroyHash(hHash); 
hHash = 0; 
} 
//--------------------------------------------------------------------
//到此为止已经产生了会话密钥。
//如果会话密钥不是从口令获取的,则会话密钥用加密者的私钥加密后
//存放到了密文文件中了。 
 
//--------------------------------------------------------------------
// 判断一次加密的字节数,必须是ENCRYPT_BLOCK_SIZE的倍数。

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("缓冲区内存已分配\n");
}
else
{ 
    HandleError("内存溢出\n"); 
}
//--------------------------------------------------------------------
//循环加密文件

do 
{ 

dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); 
if(ferror(hSource))
{ 
    HandleError("读取明文失败!\n");
}
 
//加密数据。
if(!CryptEncrypt(
     hKey, 
     0, 
     feof(hSource), 
     0, 
     pbBuffer, 
     &dwCount, 
     dwBufferLen))
{ 
   HandleError("调用CryptEncrypt函数出错\n"); 
} 

//--------------------------------------------------------------------
//把加密好的数据写到密文文件

fwrite(pbBuffer, 1, dwCount, hDestination); 
if(ferror(hDestination))
{ 
    HandleError("写密文失败");
}

} 
while(!feof(hSource)); 
//当最后一个明文块加密之后退出循环
//关闭文件

if(hSource) 
    fclose(hSource); 
if(hDestination) 
    fclose(hDestination); 

//释放内存

if(pbBuffer) 
     free(pbBuffer); 
 
//销毁会话密钥

if(hKey) 
    CryptDestroyKey(hKey); 

//释放密钥交换密钥句柄

if(hXchgKey) 
    CryptDestroyKey(hXchgKey); 
 
//销毁哈希对象

if(hHash) 
    CryptDestroyHash(hHash); 

//释放CSP句柄

if(hCryptProv) 
    CryptReleaseContext(hCryptProv, 0);
return(TRUE); 
}
//错误处理函数
void HandleError(char *s)
{
    printf("在运行程序时出现错误\n");
    printf("%s\n",s);
    printf("错误代号 %x\n.",GetLastError());
    printf("程序终止运行\n");
    exit(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -