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

📄 inituser.c

📁 C++编程实践与技巧一书各章节的源码
💻 C
字号:
//decryptfile 文件解密演示程序
#include <stdio.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 

// 解密函数声明
 
BOOL CryptDecryptFile(
     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(CryptDecryptFile(szSource, szDestination, szPassword))
{
       printf("解密文件%s成功\n", szSource);
       printf("解密好的数据在文件%s中\n",szDestination);
}
else
{
      HandleError("解密文件错误!"); 
} 
} // End of main
 //--------------------------------------------------------------------
//解密函数CryptDecryptFile定义。

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

FILE *hSource; 
FILE *hDestination; 

HCRYPTPROV hCryptProv; 
HCRYPTKEY hKey; 
HCRYPTHASH hHash; 
 
PBYTE pbKeyBlob = NULL; 
DWORD dwKeyBlobLen; 
 
PBYTE pbBuffer; 
DWORD dwBlockLen; 
DWORD dwBufferLen; 
DWORD dwCount; 

BOOL status = FALSE; 
 
//--------------------------------------------------------------------
//打开需要解密的密文文件
if(!(hSource = fopen(szSource,"rb"))) 
{
   HandleError("密文文件打开失败!");
}
//--------------------------------------------------------------------
//打开要存放明文的文件

if(!(hDestination = fopen(szDestination,"wb")))
{
    HandleError("明文文件打开失败!");
} 
//--------------------------------------------------------------------
//获取默认CSP句柄
if(!CryptAcquireContext(
      &hCryptProv, 
      NULL, 
      NULL, 
      PROV_RSA_FULL, 
      0))
{
   HandleError("调用CryptAcquireContext函数出错!"); 
}
//--------------------------------------------------------------------
// 检查口令是否存在

if(!szPassword) //如果不使用口令
{ 
//--------------------------------------------------------------------
//用存储的会话密钥解密文件

//从源文件(密文)中读取密钥块长度,并分配内存。 
fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource); 
if(ferror(hSource) || feof(hSource))
{
    HandleError("文件头读取失败!"); 
}
if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen)))
{
    HandleError("内存分配错误"); 
}
//--------------------------------------------------------------------
//从源文件(密文)中读取密钥块。

fread(pbKeyBlob, 1, dwKeyBlobLen, hSource); 
if(ferror(hSource) || feof(hSource))
{
    HandleError("读取文件头失败\n"); 
}
//--------------------------------------------------------------------
//把密钥块输入到CSP中
if(!CryptImportKey(
      hCryptProv, 
      pbKeyBlob, 
      dwKeyBlobLen, 
      0, 
      0, 
      &hKey))
{
   HandleError("调用CryptImportKey函数失败!"); 
}
} 
else 
{ 

//从口令获取的会话密钥解密文件。
 
//创建哈希对象
if(!CryptCreateHash(
       hCryptProv, 
       CALG_MD5, 
       0, 
       0, 
       &hHash))
{
    HandleError("调用CryptCreateHash函数出错!");
}
//--------------------------------------------------------------------
//把口令增加到哈希对象 
if(!CryptHashData(
       hHash, 
       (BYTE *)szPassword, 
       strlen(szPassword), 
       0)) 
{
    HandleError("调用CryptHashData函数出错!"); 
}
//--------------------------------------------------------------------
//从哈希对象获取会话密钥。

if(!CryptDeriveKey(
      hCryptProv, 
      ENCRYPT_ALGORITHM, 
      hHash, 
      0, 
      &hKey))
{ 
   HandleError("调用CryptDeriveKey函数失败!"); 
}
//--------------------------------------------------------------------
//销毁哈希对象

CryptDestroyHash(hHash); 
hHash = 0; 
} 
//--------------------------------------------------------------------
//到此为止已经产生了用于解密的会话密钥。
//可能是从密钥块中获取的,也可能是从口令中获取。
 
//判断一次解密的字节数,它必须是ENCRYPT_BLOCK_SIZE的倍数。

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(pbKeyBlob) 
     free(pbKeyBlob);

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

if(hKey) 
    CryptDestroyKey(hKey); 

//销毁哈希对象
if(hHash) 
    CryptDestroyHash(hHash); 

//释放CSP句柄

if(hCryptProv) 
    CryptReleaseContext(hCryptProv, 0); 

return status;
} 
}
//错误处理函数
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 + -